From 683d490074d93baa8a47db7ec43b7bd31145a12a Mon Sep 17 00:00:00 2001 From: Mark Donszelmann Date: Thu, 5 Nov 2009 23:00:15 +0100 Subject: Tar file expanded and committed --- src/assembly/bin.xml | 38 + src/changes/changes.xml | 60 + .../net/sf/antcontrib/cpptasks/AboutCCTask.java | 49 + .../java/net/sf/antcontrib/cpptasks/ArchEnum.java | 72 + .../java/net/sf/antcontrib/cpptasks/CCTask.java | 1440 +++++++++ .../antcontrib/cpptasks/CCTaskProgressMonitor.java | 58 + .../java/net/sf/antcontrib/cpptasks/CPUEnum.java | 71 + .../java/net/sf/antcontrib/cpptasks/CUtil.java | 523 +++ .../net/sf/antcontrib/cpptasks/CompilerDef.java | 502 +++ .../net/sf/antcontrib/cpptasks/CompilerEnum.java | 262 ++ .../net/sf/antcontrib/cpptasks/CompilerParam.java | 33 + .../net/sf/antcontrib/cpptasks/DependencyInfo.java | 86 + .../sf/antcontrib/cpptasks/DependencyTable.java | 610 ++++ .../net/sf/antcontrib/cpptasks/DistributerDef.java | 243 ++ .../net/sf/antcontrib/cpptasks/DistributerMap.java | 218 ++ .../cpptasks/DistributerProtocolEnum.java | 50 + .../net/sf/antcontrib/cpptasks/FileVisitor.java | 27 + .../java/net/sf/antcontrib/cpptasks/LinkerDef.java | 509 +++ .../net/sf/antcontrib/cpptasks/LinkerEnum.java | 112 + .../net/sf/antcontrib/cpptasks/LinkerParam.java | 33 + .../net/sf/antcontrib/cpptasks/OSFamilyEnum.java | 59 + .../antcontrib/cpptasks/ObjectFileCollector.java | 42 + .../sf/antcontrib/cpptasks/OptimizationEnum.java | 82 + .../net/sf/antcontrib/cpptasks/OutputTypeEnum.java | 48 + .../net/sf/antcontrib/cpptasks/PrecompileDef.java | 212 ++ .../antcontrib/cpptasks/PrecompileExceptDef.java | 80 + .../net/sf/antcontrib/cpptasks/ProcessorDef.java | 679 ++++ .../sf/antcontrib/cpptasks/ProcessorEnumValue.java | 47 + .../net/sf/antcontrib/cpptasks/ProcessorParam.java | 100 + .../net/sf/antcontrib/cpptasks/RuntimeType.java | 26 + .../net/sf/antcontrib/cpptasks/SourceHistory.java | 51 + .../net/sf/antcontrib/cpptasks/SubsystemEnum.java | 34 + .../java/net/sf/antcontrib/cpptasks/TargetDef.java | 228 ++ .../net/sf/antcontrib/cpptasks/TargetHistory.java | 58 + .../sf/antcontrib/cpptasks/TargetHistoryTable.java | 430 +++ .../net/sf/antcontrib/cpptasks/TargetInfo.java | 127 + .../net/sf/antcontrib/cpptasks/TargetMatcher.java | 120 + .../net/sf/antcontrib/cpptasks/VersionInfo.java | 671 ++++ .../sf/antcontrib/cpptasks/WarningLevelEnum.java | 40 + .../cpptasks/apple/PropertyListSerialization.java | 235 ++ .../cpptasks/apple/XcodeProjectWriter.java | 1016 ++++++ .../net/sf/antcontrib/cpptasks/apple/package.html | 27 + .../sf/antcontrib/cpptasks/arm/ADSCCompiler.java | 210 ++ .../sf/antcontrib/cpptasks/arm/ADSLibrarian.java | 159 + .../net/sf/antcontrib/cpptasks/arm/ADSLinker.java | 166 + .../cpptasks/borland/BorlandCCompiler.java | 134 + .../cpptasks/borland/BorlandCfgParser.java | 70 + .../cpptasks/borland/BorlandLibrarian.java | 219 ++ .../antcontrib/cpptasks/borland/BorlandLinker.java | 293 ++ .../cpptasks/borland/BorlandProcessor.java | 219 ++ .../cpptasks/borland/BorlandResourceCompiler.java | 129 + .../cpptasks/borland/CBuilderXProjectWriter.java | 542 ++++ .../cpptasks/borland/CfgFilenameState.java | 46 + .../cpptasks/borland/ConsumeToSpaceOrNewLine.java | 30 + .../cpptasks/borland/QuoteBranchState.java | 35 + .../sf/antcontrib/cpptasks/borland/package.html | 27 + .../compaq/CompaqVisualFortranCompiler.java | 137 + .../compaq/CompaqVisualFortranLibrarian.java | 82 + .../cpptasks/compaq/CompaqVisualFortranLinker.java | 77 + .../cpptasks/compiler/AbstractCompiler.java | 207 ++ .../cpptasks/compiler/AbstractLinker.java | 122 + .../cpptasks/compiler/AbstractProcessor.java | 129 + .../cpptasks/compiler/CaptureStreamHandler.java | 122 + .../cpptasks/compiler/CommandLineCCompiler.java | 42 + .../cpptasks/compiler/CommandLineCompiler.java | 437 +++ .../compiler/CommandLineCompilerConfiguration.java | 226 ++ .../compiler/CommandLineFortranCompiler.java | 42 + .../cpptasks/compiler/CommandLineLinker.java | 407 +++ .../compiler/CommandLineLinkerConfiguration.java | 128 + .../sf/antcontrib/cpptasks/compiler/Compiler.java | 24 + .../cpptasks/compiler/CompilerConfiguration.java | 64 + .../sf/antcontrib/cpptasks/compiler/LinkType.java | 150 + .../sf/antcontrib/cpptasks/compiler/Linker.java | 80 + .../cpptasks/compiler/LinkerConfiguration.java | 33 + .../compiler/PrecompilingCommandLineCCompiler.java | 43 + .../compiler/PrecompilingCommandLineCompiler.java | 104 + .../cpptasks/compiler/PrecompilingCompiler.java | 49 + .../sf/antcontrib/cpptasks/compiler/Processor.java | 75 + .../cpptasks/compiler/ProcessorConfiguration.java | 54 + .../cpptasks/compiler/ProgressMonitor.java | 31 + .../cpptasks/devstudio/DevStudio2005CCompiler.java | 62 + .../cpptasks/devstudio/DevStudioCCompiler.java | 50 + .../devstudio/DevStudioCompatibleCCompiler.java | 136 + .../devstudio/DevStudioCompatibleLibrarian.java | 80 + .../devstudio/DevStudioCompatibleLinker.java | 148 + .../cpptasks/devstudio/DevStudioLibrarian.java | 36 + .../cpptasks/devstudio/DevStudioLinker.java | 44 + .../cpptasks/devstudio/DevStudioMIDLCompiler.java | 112 + .../cpptasks/devstudio/DevStudioProcessor.java | 90 + .../cpptasks/devstudio/DevStudioProjectWriter.java | 710 +++++ .../devstudio/DevStudioResourceCompiler.java | 119 + .../devstudio/VisualStudioNETProjectWriter.java | 866 +++++ .../sf/antcontrib/cpptasks/devstudio/package.html | 27 + .../cpptasks/gcc/AbstractArLibrarian.java | 107 + .../antcontrib/cpptasks/gcc/AbstractLdLinker.java | 339 ++ .../sf/antcontrib/cpptasks/gcc/GccCCompiler.java | 242 ++ .../cpptasks/gcc/GccCompatibleCCompiler.java | 146 + .../sf/antcontrib/cpptasks/gcc/GccLibrarian.java | 41 + .../net/sf/antcontrib/cpptasks/gcc/GccLinker.java | 210 ++ .../sf/antcontrib/cpptasks/gcc/GccProcessor.java | 299 ++ .../net/sf/antcontrib/cpptasks/gcc/GppLinker.java | 203 ++ .../net/sf/antcontrib/cpptasks/gcc/LdLinker.java | 57 + .../cpptasks/gcc/WindresResourceCompiler.java | 121 + .../cpptasks/gcc/cross/GccCCompiler.java | 272 ++ .../cpptasks/gcc/cross/GccLibrarian.java | 69 + .../antcontrib/cpptasks/gcc/cross/GccLinker.java | 234 ++ .../cpptasks/gcc/cross/GccProcessor.java | 288 ++ .../antcontrib/cpptasks/gcc/cross/GppLinker.java | 228 ++ .../sf/antcontrib/cpptasks/gcc/cross/LdLinker.java | 83 + .../gcc/cross/sparc_sun_solaris2/GccCCompiler.java | 244 ++ .../gcc/cross/sparc_sun_solaris2/GccLibrarian.java | 43 + .../gcc/cross/sparc_sun_solaris2/GccLinker.java | 215 ++ .../gcc/cross/sparc_sun_solaris2/GccProcessor.java | 305 ++ .../gcc/cross/sparc_sun_solaris2/GppLinker.java | 210 ++ .../gcc/cross/sparc_sun_solaris2/LdLinker.java | 60 + .../net/sf/antcontrib/cpptasks/hp/aCCCompiler.java | 116 + .../net/sf/antcontrib/cpptasks/hp/aCCLinker.java | 100 + .../cpptasks/ibm/VisualAgeCCompiler.java | 118 + .../antcontrib/cpptasks/ibm/VisualAgeLinker.java | 83 + .../net/sf/antcontrib/cpptasks/ide/CommentDef.java | 47 + .../net/sf/antcontrib/cpptasks/ide/DebugDef.java | 127 + .../sf/antcontrib/cpptasks/ide/DependencyDef.java | 77 + .../net/sf/antcontrib/cpptasks/ide/ProjectDef.java | 372 +++ .../sf/antcontrib/cpptasks/ide/ProjectWriter.java | 53 + .../antcontrib/cpptasks/ide/ProjectWriterEnum.java | 105 + .../net/sf/antcontrib/cpptasks/ide/package.html | 27 + .../cpptasks/intel/IntelLinux32CCompiler.java | 58 + .../cpptasks/intel/IntelLinux32Linker.java | 55 + .../cpptasks/intel/IntelLinux64CCompiler.java | 58 + .../cpptasks/intel/IntelLinux64Linker.java | 55 + .../antcontrib/cpptasks/intel/IntelProcessor.java | 51 + .../cpptasks/intel/IntelWin32CCompiler.java | 52 + .../cpptasks/intel/IntelWin32Librarian.java | 38 + .../cpptasks/intel/IntelWin32Linker.java | 46 + .../cpptasks/intel/IntelWin64CCompiler.java | 53 + .../antcontrib/cpptasks/mozilla/XpidlCompiler.java | 365 +++ .../sf/antcontrib/cpptasks/mozilla/package.html | 27 + .../cpptasks/openwatcom/OpenWatcomCCompiler.java | 84 + .../cpptasks/openwatcom/OpenWatcomCLinker.java | 69 + .../cpptasks/openwatcom/OpenWatcomCompiler.java | 169 + .../openwatcom/OpenWatcomFortranCompiler.java | 86 + .../openwatcom/OpenWatcomFortranLinker.java | 69 + .../cpptasks/openwatcom/OpenWatcomLibrarian.java | 254 ++ .../cpptasks/openwatcom/OpenWatcomLinker.java | 205 ++ .../cpptasks/openwatcom/OpenWatcomProcessor.java | 169 + .../sf/antcontrib/cpptasks/openwatcom/package.html | 27 + .../antcontrib/cpptasks/os390/OS390CCompiler.java | 156 + .../sf/antcontrib/cpptasks/os390/OS390Linker.java | 208 ++ .../antcontrib/cpptasks/os390/OS390Processor.java | 71 + .../sf/antcontrib/cpptasks/os400/IccCompiler.java | 123 + .../sf/antcontrib/cpptasks/os400/IccLinker.java | 209 ++ .../sf/antcontrib/cpptasks/os400/IccProcessor.java | 71 + .../java/net/sf/antcontrib/cpptasks/package.html | 27 + .../antcontrib/cpptasks/parser/AbstractParser.java | 67 + .../cpptasks/parser/AbstractParserState.java | 41 + .../sf/antcontrib/cpptasks/parser/BranchState.java | 46 + .../net/sf/antcontrib/cpptasks/parser/CParser.java | 78 + .../parser/CaseInsensitiveLetterState.java | 87 + .../antcontrib/cpptasks/parser/FilenameState.java | 41 + .../antcontrib/cpptasks/parser/FortranParser.java | 106 + .../sf/antcontrib/cpptasks/parser/LetterState.java | 80 + .../net/sf/antcontrib/cpptasks/parser/Parser.java | 28 + .../net/sf/antcontrib/cpptasks/parser/PostE.java | 41 + .../WhitespaceOrCaseInsensitiveLetterState.java | 83 + .../cpptasks/parser/WhitespaceOrLetterState.java | 75 + .../net/sf/antcontrib/cpptasks/parser/package.html | 28 + .../cpptasks/platforms/WindowsPlatform.java | 364 +++ .../sf/antcontrib/cpptasks/platforms/package.html | 27 + .../sf/antcontrib/cpptasks/sun/C89CCompiler.java | 108 + .../net/sf/antcontrib/cpptasks/sun/C89Linker.java | 132 + .../sf/antcontrib/cpptasks/sun/C89Processor.java | 116 + .../antcontrib/cpptasks/sun/ForteCCCompiler.java | 130 + .../sf/antcontrib/cpptasks/sun/ForteCCLinker.java | 100 + .../sf/antcontrib/cpptasks/ti/ClxxCCompiler.java | 191 ++ .../sf/antcontrib/cpptasks/ti/ClxxLibrarian.java | 162 + .../net/sf/antcontrib/cpptasks/ti/ClxxLinker.java | 181 ++ .../cpptasks/trolltech/MetaObjectCompiler.java | 280 ++ .../cpptasks/trolltech/MetaObjectParser.java | 148 + .../cpptasks/trolltech/UserInterfaceCompiler.java | 347 ++ .../cpptasks/trolltech/UserInterfaceParser.java | 67 + .../sf/antcontrib/cpptasks/trolltech/package.html | 27 + .../cpptasks/types/CommandLineArgument.java | 104 + .../cpptasks/types/CompilerArgument.java | 28 + .../cpptasks/types/ConditionalFileSet.java | 84 + .../antcontrib/cpptasks/types/ConditionalPath.java | 75 + .../antcontrib/cpptasks/types/DefineArgument.java | 38 + .../sf/antcontrib/cpptasks/types/DefineSet.java | 199 ++ .../net/sf/antcontrib/cpptasks/types/FlexLong.java | 59 + .../sf/antcontrib/cpptasks/types/IncludePath.java | 38 + .../sf/antcontrib/cpptasks/types/LibrarySet.java | 347 ++ .../antcontrib/cpptasks/types/LibraryTypeEnum.java | 48 + .../antcontrib/cpptasks/types/LinkerArgument.java | 28 + .../cpptasks/types/SystemIncludePath.java | 45 + .../cpptasks/types/SystemLibrarySet.java | 37 + .../cpptasks/types/UndefineArgument.java | 153 + src/main/resources/META-INF/LICENSE | 202 ++ src/main/resources/META-INF/NOTICE | 4 + src/main/resources/cpptasks.tasks | 1 + src/main/resources/cpptasks.types | 8 + .../net/sf/antcontrib/cpptasks/antlib.xml | 22 + src/samples/blas.ant | 185 ++ src/samples/check.ant | 206 ++ src/samples/cppunit.ant | 583 ++++ src/samples/hello/build.xml | 27 + src/samples/hello/src/main/c/hello.c | 25 + src/samples/qtunit.ant | 238 ++ src/samples/xercesc.ant | 1113 +++++++ src/samples/xpcom.ant | 120 + src/site/apt/index.apt | 71 + src/site/site.xml | 69 + src/site/xdoc/antdocs/CCTask.xml | 534 ++++ src/site/xdoc/antdocs/CommentDef.xml | 37 + src/site/xdoc/antdocs/CompilerArgument.xml | 83 + src/site/xdoc/antdocs/CompilerDef.xml | 313 ++ src/site/xdoc/antdocs/CompilerParam.xml | 81 + src/site/xdoc/antdocs/ConditionalFileSet.xml | 221 ++ src/site/xdoc/antdocs/ConditionalPath.xml | 122 + src/site/xdoc/antdocs/DebugDef.xml | 76 + src/site/xdoc/antdocs/DefineArgument.xml | 76 + src/site/xdoc/antdocs/DefineSet.xml | 111 + src/site/xdoc/antdocs/DependencyDef.xml | 64 + src/site/xdoc/antdocs/DistributerDef.xml | 113 + src/site/xdoc/antdocs/DistributerMap.xml | 96 + src/site/xdoc/antdocs/IncludePath.xml | 125 + src/site/xdoc/antdocs/LibrarySet.xml | 114 + src/site/xdoc/antdocs/LinkerArgument.xml | 83 + src/site/xdoc/antdocs/LinkerDef.xml | 284 ++ src/site/xdoc/antdocs/LinkerParam.xml | 81 + src/site/xdoc/antdocs/PrecompileDef.xml | 99 + src/site/xdoc/antdocs/PrecompileExceptDef.xml | 64 + src/site/xdoc/antdocs/ProjectDef.xml | 166 + src/site/xdoc/antdocs/SystemIncludePath.xml | 132 + src/site/xdoc/antdocs/SystemLibrarySet.xml | 116 + src/site/xdoc/antdocs/TargetDef.xml | 105 + src/site/xdoc/antdocs/UndefineArgument.xml | 71 + src/site/xdoc/antdocs/VersionInfo.xml | 187 ++ .../net/sf/antcontrib/taskdocs/TaskDoclet.java | 1 + .../net/sf/antcontrib/taskdocs/element.xslt | 210 ++ .../sf/antcontrib/cpptasks/MockBuildListener.java | 172 + .../sf/antcontrib/cpptasks/MockFileCollector.java | 90 + .../net/sf/antcontrib/cpptasks/TestAllClasses.java | 63 + .../net/sf/antcontrib/cpptasks/TestCCTask.java | 128 + .../java/net/sf/antcontrib/cpptasks/TestCUtil.java | 153 + .../sf/antcontrib/cpptasks/TestCompilerDef.java | 357 +++ .../sf/antcontrib/cpptasks/TestCompilerEnum.java | 51 + .../antcontrib/cpptasks/TestDependencyTable.java | 73 + .../net/sf/antcontrib/cpptasks/TestLinkerDef.java | 374 +++ .../net/sf/antcontrib/cpptasks/TestLinkerEnum.java | 40 + .../sf/antcontrib/cpptasks/TestOutputTypeEnum.java | 39 + .../sf/antcontrib/cpptasks/TestProcessorDef.java | 278 ++ .../cpptasks/TestTargetHistoryTable.java | 141 + .../net/sf/antcontrib/cpptasks/TestTargetInfo.java | 134 + .../sf/antcontrib/cpptasks/TestXMLConsumer.java | 96 + .../cpptasks/borland/TestBorlandCCompiler.java | 37 + .../cpptasks/compiler/TestAbstractCompiler.java | 85 + .../cpptasks/compiler/TestAbstractLinker.java | 89 + .../cpptasks/compiler/TestAbstractProcessor.java | 80 + .../TestCommandLineCompilerConfiguration.java | 59 + .../compiler/TestCompilerConfiguration.java | 68 + .../antcontrib/cpptasks/compiler/TestLinkType.java | 59 + .../devstudio/TestDevStudio2005CCompiler.java | 41 + .../cpptasks/devstudio/TestDevStudioCCompiler.java | 41 + .../cpptasks/devstudio/TestDevStudioLinker.java | 44 + .../devstudio/TestInstalledDevStudioLinker.java | 60 + .../cpptasks/gcc/TestAbstractArLibrarian.java | 79 + .../cpptasks/gcc/TestAbstractLdLinker.java | 247 ++ .../antcontrib/cpptasks/gcc/TestGccCCompiler.java | 80 + .../cpptasks/gcc/TestGccCompatibleCCompiler.java | 105 + .../sf/antcontrib/cpptasks/gcc/TestGccLinker.java | 79 + .../sf/antcontrib/cpptasks/hp/TestaCCCompiler.java | 93 + .../cpptasks/ibm/TestVisualAgeCCompiler.java | 68 + .../java/net/sf/antcontrib/cpptasks/package.html | 28 + .../sf/antcontrib/cpptasks/parser/TestCParser.java | 199 ++ .../cpptasks/parser/TestFortranParser.java | 81 + .../net/sf/antcontrib/cpptasks/parser/package.html | 27 + .../cpptasks/sun/TestForteCCCompiler.java | 132 + .../cpptasks/trolltech/TestMetaObjectCompiler.java | 74 + .../cpptasks/trolltech/TestMetaObjectParser.java | 58 + .../sf/antcontrib/cpptasks/trolltech/package.html | 27 + .../cpptasks/types/TestDefineArgument.java | 124 + .../antcontrib/cpptasks/types/TestLibrarySet.java | 337 ++ .../net/sf/antcontrib/cpptasks/types/package.html | 28 + src/test/resources/openshore/dependencies.xml | 911 ++++++ src/test/resources/openshore/history.xml | 74 + src/test/resources/xerces-c/dependencies.xml | 3330 ++++++++++++++++++++ src/test/resources/xerces-c/history.xml | 636 ++++ 286 files changed, 45900 insertions(+) create mode 100644 src/assembly/bin.xml create mode 100644 src/changes/changes.xml create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CCTask.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CUtil.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/apple/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/borland/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ide/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/parser/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java create mode 100644 src/main/resources/META-INF/LICENSE create mode 100644 src/main/resources/META-INF/NOTICE create mode 100644 src/main/resources/cpptasks.tasks create mode 100644 src/main/resources/cpptasks.types create mode 100644 src/main/resources/net/sf/antcontrib/cpptasks/antlib.xml create mode 100644 src/samples/blas.ant create mode 100644 src/samples/check.ant create mode 100644 src/samples/cppunit.ant create mode 100644 src/samples/hello/build.xml create mode 100644 src/samples/hello/src/main/c/hello.c create mode 100644 src/samples/qtunit.ant create mode 100644 src/samples/xercesc.ant create mode 100644 src/samples/xpcom.ant create mode 100644 src/site/apt/index.apt create mode 100644 src/site/site.xml create mode 100644 src/site/xdoc/antdocs/CCTask.xml create mode 100644 src/site/xdoc/antdocs/CommentDef.xml create mode 100644 src/site/xdoc/antdocs/CompilerArgument.xml create mode 100644 src/site/xdoc/antdocs/CompilerDef.xml create mode 100644 src/site/xdoc/antdocs/CompilerParam.xml create mode 100644 src/site/xdoc/antdocs/ConditionalFileSet.xml create mode 100644 src/site/xdoc/antdocs/ConditionalPath.xml create mode 100644 src/site/xdoc/antdocs/DebugDef.xml create mode 100644 src/site/xdoc/antdocs/DefineArgument.xml create mode 100644 src/site/xdoc/antdocs/DefineSet.xml create mode 100644 src/site/xdoc/antdocs/DependencyDef.xml create mode 100644 src/site/xdoc/antdocs/DistributerDef.xml create mode 100644 src/site/xdoc/antdocs/DistributerMap.xml create mode 100644 src/site/xdoc/antdocs/IncludePath.xml create mode 100644 src/site/xdoc/antdocs/LibrarySet.xml create mode 100644 src/site/xdoc/antdocs/LinkerArgument.xml create mode 100644 src/site/xdoc/antdocs/LinkerDef.xml create mode 100644 src/site/xdoc/antdocs/LinkerParam.xml create mode 100644 src/site/xdoc/antdocs/PrecompileDef.xml create mode 100644 src/site/xdoc/antdocs/PrecompileExceptDef.xml create mode 100644 src/site/xdoc/antdocs/ProjectDef.xml create mode 100644 src/site/xdoc/antdocs/SystemIncludePath.xml create mode 100644 src/site/xdoc/antdocs/SystemLibrarySet.xml create mode 100644 src/site/xdoc/antdocs/TargetDef.xml create mode 100644 src/site/xdoc/antdocs/UndefineArgument.xml create mode 100644 src/site/xdoc/antdocs/VersionInfo.xml create mode 100644 src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java create mode 100644 src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/MockBuildListener.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/MockFileCollector.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestAllClasses.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestCCTask.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestCUtil.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestCompilerDef.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestCompilerEnum.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestDependencyTable.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestLinkerDef.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestLinkerEnum.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestOutputTypeEnum.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestProcessorDef.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestTargetHistoryTable.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestTargetInfo.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/TestXMLConsumer.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/borland/TestBorlandCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractLinker.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractProcessor.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCommandLineCompilerConfiguration.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCompilerConfiguration.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/compiler/TestLinkType.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudio2005CCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioLinker.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestInstalledDevStudioLinker.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractArLibrarian.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractLdLinker.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCompatibleCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccLinker.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/hp/TestaCCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/ibm/TestVisualAgeCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/package.html create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/parser/TestCParser.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/parser/TestFortranParser.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/parser/package.html create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/sun/TestForteCCCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectCompiler.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectParser.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/trolltech/package.html create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/types/TestDefineArgument.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/types/TestLibrarySet.java create mode 100644 src/test/java/net/sf/antcontrib/cpptasks/types/package.html create mode 100644 src/test/resources/openshore/dependencies.xml create mode 100644 src/test/resources/openshore/history.xml create mode 100644 src/test/resources/xerces-c/dependencies.xml create mode 100644 src/test/resources/xerces-c/history.xml (limited to 'src') diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml new file mode 100644 index 0000000..f57609f --- /dev/null +++ b/src/assembly/bin.xml @@ -0,0 +1,38 @@ + + + bin + + zip + tar.gz + + cpptasks-${project.version} + true + + + + *.xml + INSTALL + KEYS + LICENSE + NOTICE + src/** + + + + diff --git a/src/changes/changes.xml b/src/changes/changes.xml new file mode 100644 index 0000000..4782965 --- /dev/null +++ b/src/changes/changes.xml @@ -0,0 +1,60 @@ + + + + cpptasks: Compile tasks for Apache Ant + + + + + IDE project file generation. + history.xml not capturing mid and end arguments + LinkerDef not properly capturing references + Update documentation for antlib usage + Modify warning levels for sunpro + Modify CC, aCC and xlC to bid on .s files + Add msvc8 compiler to avoid deprecation warning on /GZ + Migrate to Maven 2 for build and documentation + Fix linked issues with shared libraries on VisualAge + + + + + + + Sample build file for CPPUNIT + Borland compilation repair + Problem with linker extension + Added type attribute to libset and syslibset so that dynamic or static could be chosen if both were available + Added rtti and optimization attributes to cc and compiler + Added versioninfo element (experimental) + Add target element for cross-compilation (experimental) + Add distributer element for distributed builds (experimental) + + + + + + + + + + + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java b/src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java new file mode 100644 index 0000000..4f17111 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/AboutCCTask.java @@ -0,0 +1,49 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +/** + * The equivalent of a Help About + * run "java -jar cpptasks.jar" to read + * + * @author Curt Arnold + */ +public class AboutCCTask { + /** + * display identification message and exit + * + * @param args ignored + */ + public static void main(String args[]) { + System.out.println("CCTask: Compile and link task for Apache Ant 1.5 or later\n"); + System.out.println("Copyright (c) 2002-2004, The Ant-Contrib project.\n"); + System.out.println("http://sf.net/projects/ant-contrib\n"); + System.out.println("Licensed under the Apache Software License 2.0"); + System.out.println("available at http://www.apache.org/licenses/LICENSE-2.0\n"); + System.out.println("This software is not a product of the"); + System.out.println("of the Apache Software Foundation and no"); + System.out.println("endorsement or promotion is implied.\n"); + System.out.println("THIS SOFTWARE IS PROVIDED 'AS-IS', See"); + System.out.println("http://www.apache.org/LICENSE for additional"); + System.out.println("disclaimers.\n"); + System.out.println("To use:"); + System.out.println("\tPlace cpptasks.jar into lib directory of Ant 1.5 or later."); + System.out.println("\tAdd and"); + System.out.println("\t\t to build.xml"); + System.out.println("Add , ; and elements."); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java new file mode 100644 index 0000000..0f36405 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ArchEnum.java @@ -0,0 +1,72 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Enumeration of cpu architecture types. + * + * @author Curt Arnold + * + */ +public final class ArchEnum + extends EnumeratedAttribute { + /** + * Constructor. + * + * Set by default to "pentium3" + * + * @see java.lang.Object#Object() + */ + public ArchEnum() { + setValue("pentium3"); + } + + /** + * Gets list of acceptable values. + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + /** + * Class initializer. + */ + return new String[] { + "i386", + "i486", + "i586", + "i686", + "pentium", + "pentium-mmx", + "pentiumpro", + "pentium2", + "pentium3", + "pentium4", + "k6", + "k6-2", + "k6-3", + "athlon", + "athlon-tbird", + "athlon-4", + "athlon-xp", + "athlon-mp", + "winchip-c6", + "winchip2", + "c3"}; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java b/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java new file mode 100644 index 0000000..2e6adab --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java @@ -0,0 +1,1440 @@ +/* + * + * Copyright 2001-2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.*; + +import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.LinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.ide.ProjectDef; +import net.sf.antcontrib.cpptasks.types.CompilerArgument; +import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; +import net.sf.antcontrib.cpptasks.types.DefineSet; +import net.sf.antcontrib.cpptasks.types.IncludePath; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LinkerArgument; +import net.sf.antcontrib.cpptasks.types.SystemIncludePath; +import net.sf.antcontrib.cpptasks.types.SystemLibrarySet; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Environment; +/** + * Compile and link task. + * + *

+ * This task can compile various source languages and produce executables, + * shared libraries (aka DLL's) and static libraries. Compiler adaptors are + * currently available for several C/C++ compilers, FORTRAN, MIDL and Windows + * Resource files. + *

+ * + *

+ * Copyright (c) 2001-2008, The Ant-Contrib project. + *

+ * + *

+ * Licensed under the Apache Software License 2.0, + * http://www.apache.org/licenses/LICENSE-2.0. + *

+ * + *

+ * For use with Apache Ant 1.5 or later. This software is not a product of the + * of the Apache Software Foundation and no endorsement is implied. + *

+ * + *

+ * THIS SOFTWARE IS PROVIDED 'AS-IS', See + * http://www.apache.org/licenses/LICENSE-2.0 for additional disclaimers. + *

+ * + * To use: + *
    + *
  1. + * Place cpptasks.jar into Ant's classpath by placing it in Ant's lib + * directory, adding it to the CLASSPATH environment variable or by using the + * -lib command line option. + *
  2. + *
  3. + * Add type and task definitions to the build file: + *
      + *
    • + * Ant 1.6 or later: + *
        + *
      • Add xmlns:cpptasks="antlib:net.sf.antcontrib.cpptasks" to + * <project> element. + *
      • + *
      • + * Add <cpptasks:cc/>, <cpptasks:compiler/> and + * <cpptasks:linker/> elements to the project. + *
      • + *
      + *
    • + *
    • + * Ant 1.5 or later: + *
        + *
      • Add <taskdef resource="cpptasks.tasks"/> and + * <typedef resource="cpptasks.types"/> to body of <project> + * element. + *
      • + *
      • + * Add <cc/>, <compiler/> and <linker/> elements to the + * project. + *
      • + *
      + *
    • + *
    + *
  4. + *
  5. + * Set the path and environment variables to be able to run compiler from + * command line. + *
  6. + *
  7. + * Build the project. + *
  8. + *
+ * + * @author Adam Murdoch + * @author Curt Arnold + */ +public class CCTask extends Task { + private static class SystemLibraryCollector implements FileVisitor { + private Hashtable libraries; + private Linker linker; + public SystemLibraryCollector(Linker linker, Hashtable libraries) { + this.linker = linker; + this.libraries = libraries; + } + public void visit(File basedir, String filename) { + if (linker.bid(filename) > 0) { + File libfile = new File(basedir, filename); + String key = linker.getLibraryKey(libfile); + libraries.put(key, libfile); + } + } + } + + private static class ProjectFileCollector implements FileVisitor { + private final List files; + /** + * Creates a new ProjectFileCollector. + * @param files vector for collected files. + */ + public ProjectFileCollector(List files) { + this.files = files; + } + /** + * Called for each file to be considered for collection. + * @param parentDir parent directory + * @param filename filename within directory + */ + public void visit(File parentDir, String filename) { + files.add(new File(parentDir, filename)); + } + } + + private static final ProcessorConfiguration[] EMPTY_CONFIG_ARRAY = new ProcessorConfiguration[0]; + /** + * Builds a Hashtable to targets needing to be rebuilt keyed by compiler + * configuration + */ + public static Hashtable getTargetsToBuildByConfiguration(Hashtable targets) { + Hashtable targetsByConfig = new Hashtable(); + Enumeration targetEnum = targets.elements(); + while (targetEnum.hasMoreElements()) { + TargetInfo target = (TargetInfo) targetEnum.nextElement(); + if (target.getRebuild()) { + Vector targetsForSameConfig = (Vector) targetsByConfig + .get(target.getConfiguration()); + if (targetsForSameConfig != null) { + targetsForSameConfig.addElement(target); + } else { + targetsForSameConfig = new Vector(); + targetsForSameConfig.addElement(target); + targetsByConfig.put(target.getConfiguration(), + targetsForSameConfig); + } + } + } + return targetsByConfig; + } + /** The compiler definitions. */ + private Vector _compilers = new Vector(); + /** The output file type. */ + // private LinkType _linkType = LinkType.EXECUTABLE; + /** The library sets. */ + private Vector _libsets = new Vector(); + /** The linker definitions. */ + private Vector _linkers = new Vector(); + /** The object directory. */ + private File _objDir; + /** The output file. */ + private File _outfile; + /** The linker definitions. */ + private final Vector targetPlatforms = new Vector(); + /** The distributer definitions. */ + private Vector distributers = new Vector(); + private final Vector versionInfos = new Vector(); + private final Vector projects = new Vector(); + private boolean projectsOnly = false; + + + /** + * If true, stop build on compile failure. + */ + protected boolean failOnError = true; + + /** + * Content that appears in and also in are maintained by a + * captive CompilerDef instance + */ + private final CompilerDef compilerDef = new CompilerDef(); + /** The OS390 dataset to build to object to */ + private String dataset; + /** + * + * Depth of dependency checking + * + * Values < 0 indicate full dependency checking Values >= 0 indicate + * partial dependency checking and for superficial compilation checks. Will + * throw BuildException before attempting link + */ + private int dependencyDepth = -1; + /** + * Content that appears in and also in are maintained by a + * captive CompilerDef instance + */ + private final LinkerDef linkerDef = new LinkerDef(); + /** + * contains the subsystem, output type and + * + */ + private final LinkType linkType = new LinkType(); + /** + * The property name which will be set with the physical filename of the + * file that is generated by the linker + */ + private String outputFileProperty; + /** + * if relentless = true, compilations should attempt to compile as many + * files as possible before throwing a BuildException + */ + private boolean relentless; + public CCTask() { + } + /** + * Adds a compiler definition or reference. + * + * @param compiler + * compiler + * @throws NullPointerException + * if compiler is null + */ + public void addConfiguredCompiler(CompilerDef compiler) { + if (compiler == null) { + throw new NullPointerException("compiler"); + } + compiler.setProject(getProject()); + _compilers.addElement(compiler); + } + /** + * Adds a compiler command-line arg. Argument will be inherited by all + * nested compiler elements that do not have inherit="false". + * + */ + public void addConfiguredCompilerArg(CompilerArgument arg) { + compilerDef.addConfiguredCompilerArg(arg); + } + /** + * Adds a defineset. Will be inherited by all compiler elements that do not + * have inherit="false". + * + * @param defs + * Define set + */ + public void addConfiguredDefineset(DefineSet defs) { + compilerDef.addConfiguredDefineset(defs); + } + /** + * Adds a linker definition. The first linker that is not disqualified by + * its "if" and "unless" attributes will perform the link. If no child + * linker element is active, the linker implied by the cc elements name or + * classname attribute will be used. + * + * @param linker + * linker + * @throws NullPointerException + * if linker is null + */ + public void addConfiguredLinker(LinkerDef linker) { + if (linker == null) { + throw new NullPointerException("linker"); + } + linker.setProject(getProject()); + _linkers.addElement(linker); + } + /** + * Adds a linker command-line arg. Argument will be inherited by all nested + * linker elements that do not have inherit="false". + */ + public void addConfiguredLinkerArg(LinkerArgument arg) { + linkerDef.addConfiguredLinkerArg(arg); + } + /** + * Add an environment variable to the launched process. + */ + public void addEnv(Environment.Variable var) { + compilerDef.addEnv(var); + linkerDef.addEnv(var); + } + /** + * Adds a source file set. + * + * Files in these filesets will be auctioned to the available compiler + * configurations, with the default compiler implied by the cc element + * bidding last. If no compiler is interested in the file, it will be + * passed to the linker. + * + * To have a file be processed by a particular compiler configuration, add + * a fileset to the corresponding compiler element. + */ + public void addFileset(ConditionalFileSet srcSet) { + compilerDef.addFileset(srcSet); + } + /** + * Adds a library set. + * + * Library sets will be inherited by all linker elements that do not have + * inherit="false". + * + * @param libset + * library set + * @throws NullPointerException + * if libset is null. + */ + public void addLibset(LibrarySet libset) { + if (libset == null) { + throw new NullPointerException("libset"); + } + linkerDef.addLibset(libset); + } + /** + * Adds a system library set. Timestamps and locations of system library + * sets are not used in dependency analysis. + * + * Essential libraries (such as C Runtime libraries) should not be + * specified since the task will attempt to identify the correct libraries + * based on the multithread, debug and runtime attributes. + * + * System library sets will be inherited by all linker elements that do not + * have inherit="false". + * + * @param libset + * library set + * @throws NullPointerException + * if libset is null. + */ + public void addSyslibset(SystemLibrarySet libset) { + if (libset == null) { + throw new NullPointerException("libset"); + } + linkerDef.addSyslibset(libset); + } + /** + * Specifies the generation of IDE project file. Experimental. + * @param projectDef project file generation specification + */ + public void addProject(final ProjectDef projectDef) { + if (projectDef == null) { + throw new NullPointerException("projectDef"); + } + projects.addElement(projectDef); + } + public void setProjectsOnly(final boolean value) { + projectsOnly = value; + } + /** + * Checks all targets that are not forced to be rebuilt or are missing + * object files to be checked for modified include files + * + * @return total number of targets to be rebuilt + * + */ + protected int checkForChangedIncludeFiles(Hashtable targets) { + int potentialTargets = 0; + int definiteTargets = 0; + Enumeration targetEnum = targets.elements(); + while (targetEnum.hasMoreElements()) { + TargetInfo target = (TargetInfo) targetEnum.nextElement(); + if (!target.getRebuild()) { + potentialTargets++; + } else { + definiteTargets++; + } + } + // + // If there were remaining targets that + // might be out of date + // + if (potentialTargets > 0) { + log("Starting dependency analysis for " + + Integer.toString(potentialTargets) + " files."); + DependencyTable dependencyTable = new DependencyTable(_objDir); + try { + dependencyTable.load(); + } catch (Exception ex) { + log("Problem reading dependencies.xml: " + ex.toString()); + } + targetEnum = targets.elements(); + while (targetEnum.hasMoreElements()) { + TargetInfo target = (TargetInfo) targetEnum.nextElement(); + if (!target.getRebuild()) { + if (dependencyTable.needsRebuild(this, target, + dependencyDepth)) { + target.mustRebuild(); + } + } + } + dependencyTable.commit(this); + } + // + // count files being rebuilt now + // + int currentTargets = 0; + targetEnum = targets.elements(); + while (targetEnum.hasMoreElements()) { + TargetInfo target = (TargetInfo) targetEnum.nextElement(); + if (target.getRebuild()) { + currentTargets++; + } + } + if (potentialTargets > 0) { + log(Integer.toString(potentialTargets - currentTargets + + definiteTargets) + + " files are up to date."); + log(Integer.toString(currentTargets - definiteTargets) + + " files to be recompiled from dependency analysis."); + } + log(Integer.toString(currentTargets) + " total files to be compiled."); + return currentTargets; + } + protected LinkerConfiguration collectExplicitObjectFiles( + Vector objectFiles, Vector sysObjectFiles, VersionInfo versionInfo) { + // + // find the first eligible linker + // + // + ProcessorConfiguration linkerConfig = null; + LinkerDef selectedLinkerDef = null; + Linker selectedLinker = null; + Hashtable sysLibraries = new Hashtable(); + TargetDef targetPlatform = getTargetPlatform(); + FileVisitor objCollector = null; + FileVisitor sysLibraryCollector = null; + for (int i = 0; i < _linkers.size(); i++) { + LinkerDef currentLinkerDef = (LinkerDef) _linkers.elementAt(i); + if (currentLinkerDef.isActive()) { + selectedLinkerDef = currentLinkerDef; + selectedLinker = currentLinkerDef.getProcessor().getLinker( + linkType); + // + // skip the linker if it doesn't know how to + // produce the specified link type + if (selectedLinker != null) { + linkerConfig = currentLinkerDef.createConfiguration(this, + linkType, linkerDef, targetPlatform, versionInfo); + if (linkerConfig != null) { + // + // create collectors for object files + // and system libraries + objCollector = new ObjectFileCollector(selectedLinker, + objectFiles); + sysLibraryCollector = new SystemLibraryCollector( + selectedLinker, sysLibraries); + // + // if the has embedded 's + // (such as linker specific libraries) + // add them as object files. + // + if (currentLinkerDef.hasFileSets()) { + currentLinkerDef.visitFiles(objCollector); + } + // + // user libraries are just a specialized form + // of an object fileset + selectedLinkerDef.visitUserLibraries(selectedLinker, + objCollector); + } + break; + } + } + } + if (linkerConfig == null) { + linkerConfig = linkerDef.createConfiguration(this, linkType, null, targetPlatform, versionInfo); + selectedLinker = (Linker) linkerDef.getProcessor().getLinker( + linkType); + objCollector = new ObjectFileCollector(selectedLinker, objectFiles); + sysLibraryCollector = new SystemLibraryCollector(selectedLinker, + sysLibraries); + } + // + // unless there was a element that + // explicitly did not inherit files from + // containing element + if (selectedLinkerDef == null || selectedLinkerDef.getInherit()) { + linkerDef.visitUserLibraries(selectedLinker, objCollector); + linkerDef.visitSystemLibraries(selectedLinker, sysLibraryCollector); + } + // + // if there was a in a nested + // evaluate it last so it takes priority over + // identically named libs from element + // + if (selectedLinkerDef != null) { + // + // add any system libraries to the hashtable + // done in reverse order so the earliest + // on the classpath takes priority + selectedLinkerDef.visitSystemLibraries(selectedLinker, + sysLibraryCollector); + } + // + // copy over any system libraries to the + // object files vector + // + Enumeration sysLibEnum = sysLibraries.elements(); + while (sysLibEnum.hasMoreElements()) { + sysObjectFiles.addElement(sysLibEnum.nextElement()); + } + return (LinkerConfiguration) linkerConfig; + } + /** + * Adds an include path. + * + * Include paths will be inherited by nested compiler elements that do not + * have inherit="false". + */ + public IncludePath createIncludePath() { + return compilerDef.createIncludePath(); + } + /** + * Specifies precompilation prototype file and exclusions. Inherited by all + * compilers that do not have inherit="false". + * + */ + public PrecompileDef createPrecompile() throws BuildException { + return compilerDef.createPrecompile(); + } + /** + * Adds a system include path. Locations and timestamps of files located + * using the system include paths are not used in dependency analysis. + * + * + * Standard include locations should not be specified. The compiler + * adapters should recognized the settings from the appropriate environment + * variables or configuration files. + * + * System include paths will be inherited by nested compiler elements that + * do not have inherit="false". + */ + public SystemIncludePath createSysIncludePath() { + return compilerDef.createSysIncludePath(); + } + /** + * Executes the task. Compiles the given files. + * + * @throws BuildException + * if someting goes wrong with the build + */ + public void execute() throws BuildException { + // + // if link type allowed objdir to be defaulted + // provide it from outfile + if (_objDir == null) { + if(_outfile != null) { + _objDir = new File(_outfile.getParent()); + } else { + _objDir = new File("."); + } + } + + // + // if the object directory does not exist + // + if (!_objDir.exists()) { + throw new BuildException("Object directory does not exist"); + } + TargetHistoryTable objHistory = new TargetHistoryTable(this, _objDir); + + // + // get the first active version info + // + VersionInfo versionInfo = null; + Enumeration versionEnum = versionInfos.elements(); + while (versionEnum.hasMoreElements()) { + versionInfo = (VersionInfo) versionEnum.nextElement(); + versionInfo = versionInfo.merge(); + if (versionInfo.isActive()) { + break; + } else { + versionInfo = null; + } + } + + + // + // determine the eventual linker configuration + // (may be null) and collect any explicit + // object files or libraries + Vector objectFiles = new Vector(); + Vector sysObjectFiles = new Vector(); + LinkerConfiguration linkerConfig = collectExplicitObjectFiles( + objectFiles, sysObjectFiles, versionInfo); + + + // + // Assemble hashtable of all files + // that we know how to compile (keyed by output file name) + // + Hashtable targets = getTargets(linkerConfig, objectFiles, versionInfo, _outfile); + TargetInfo linkTarget = null; + // + // if output file is not specified, + // then skip link step + // + if (_outfile != null) { + linkTarget = getLinkTarget(linkerConfig, objectFiles, + sysObjectFiles, targets, versionInfo); + } + + if (projects.size() > 0) { + ArrayList files = new ArrayList(); + ProjectFileCollector matcher = new ProjectFileCollector(files); + for (int i = 0; i < _compilers.size(); i++) { + CompilerDef currentCompilerDef = (CompilerDef) _compilers + .elementAt(i); + if (currentCompilerDef.isActive()) { + if (currentCompilerDef.hasFileSets()) { + currentCompilerDef.visitFiles(matcher); + } + } + } + compilerDef.visitFiles(matcher); + + + Enumeration iter = projects.elements(); + while (iter.hasMoreElements()) { + ProjectDef projectDef = (ProjectDef) iter.nextElement(); + if (projectDef.isActive()) { + projectDef.execute(this, files, targets, linkTarget); + } + } + } + if (projectsOnly) return; + + + + // + // mark targets that don't have a history record or + // whose source last modification time is not + // the same as the history to be rebuilt + // + objHistory.markForRebuild(targets); + CCTaskProgressMonitor monitor = new CCTaskProgressMonitor(objHistory, versionInfo); + // + // check for changed include files + // + int rebuildCount = checkForChangedIncludeFiles(targets); + if (rebuildCount > 0) { + BuildException compileException = null; + // + // compile all targets with getRebuild() == true + // + Hashtable targetsByConfig = getTargetsToBuildByConfiguration(targets); + // + // build array containing Vectors with precompiled generation + // steps going first + // + Vector[] targetVectors = new Vector[targetsByConfig.size()]; + int index = 0; + Enumeration targetVectorEnum = targetsByConfig.elements(); + while (targetVectorEnum.hasMoreElements()) { + Vector targetsForConfig = (Vector) targetVectorEnum + .nextElement(); + // + // get the configuration from the first entry + // + CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig + .elementAt(0)).getConfiguration(); + if (config.isPrecompileGeneration()) { + targetVectors[index++] = targetsForConfig; + } + } + targetVectorEnum = targetsByConfig.elements(); + while (targetVectorEnum.hasMoreElements()) { + Vector targetsForConfig = (Vector) targetVectorEnum + .nextElement(); + for (int i = 0; i < targetVectors.length; i++) { + if (targetVectors[i] == targetsForConfig) { + break; + } + if (targetVectors[i] == null) { + targetVectors[i] = targetsForConfig; + break; + } + } + } + for (int i = 0; i < targetVectors.length; i++) { + // + // get the targets for this configuration + // + Vector targetsForConfig = targetVectors[i]; + // + // get the configuration from the first entry + // + CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig + .elementAt(0)).getConfiguration(); + // + // prepare the list of source files + // + String[] sourceFiles = new String[targetsForConfig.size()]; + Enumeration targetsEnum = targetsForConfig.elements(); + index = 0; + while (targetsEnum.hasMoreElements()) { + TargetInfo targetInfo = ((TargetInfo) targetsEnum + .nextElement()); + sourceFiles[index++] = targetInfo.getSources()[0] + .toString(); + } + try { + config.compile(this, _objDir, sourceFiles, relentless, + monitor); + } catch (BuildException ex) { + if (compileException == null) { + compileException = ex; + } + if (!relentless) + break; + } + } + // + // save the details of the object file compilation + // settings to disk for dependency analysis + // + try { + objHistory.commit(); + } catch (IOException ex) { + this.log("Error writing history.xml: " + ex.toString()); + } + // + // if we threw a compile exception and + // didn't throw it at the time because + // we were relentless then + // save the history and + // throw the exception + // + if (compileException != null) { + if (failOnError) { + throw compileException; + } else { + log(compileException.getMessage(), Project.MSG_ERR); + return; + } + } + } + // + // if the dependency tree was not fully + // evaluated, then throw an exception + // since we really didn't do what we + // should have done + // + // + if (dependencyDepth >= 0) { + throw new BuildException( + "All files at depth " + + Integer.toString(dependencyDepth) + + " from changes successfully compiled.\n" + + "Remove or change dependencyDepth to -1 to perform full compilation."); + } + // + // if no link target then + // commit the history for the object files + // and leave the task + if (linkTarget != null) { + // + // get the history for the link target (may be the same + // as the object history) + TargetHistoryTable linkHistory = getLinkHistory(objHistory); + // + // see if it needs to be rebuilt + // + linkHistory.markForRebuild(linkTarget); + // + // if it needs to be rebuilt, rebuild it + // + File output = linkTarget.getOutput(); + if (linkTarget.getRebuild()) { + log("Starting link"); + LinkerConfiguration linkConfig = (LinkerConfiguration) linkTarget + .getConfiguration(); + if (failOnError) { + linkConfig.link(this, linkTarget); + } else { + try { + linkConfig.link(this, linkTarget); + } catch(BuildException ex) { + log(ex.getMessage(), Project.MSG_ERR); + return; + } + } + if (outputFileProperty != null) + getProject().setProperty(outputFileProperty, + output.getAbsolutePath()); + linkHistory.update(linkTarget); + try { + linkHistory.commit(); + } catch (IOException ex) { + log("Error writing link history.xml: " + ex.toString()); + } + } else { + if (outputFileProperty != null) + getProject().setProperty(outputFileProperty, + output.getAbsolutePath()); + } + } + } + /** + * Gets the dataset. + * + * @return Returns a String + */ + public String getDataset() { + return dataset; + } + protected TargetHistoryTable getLinkHistory(TargetHistoryTable objHistory) { + File outputFileDir = new File(_outfile.getParent()); + // + // if the output file is being produced in the link + // directory, then we can use the same history file + // + if (_objDir.equals(outputFileDir)) { + return objHistory; + } + return new TargetHistoryTable(this, outputFileDir); + } + protected TargetInfo getLinkTarget(LinkerConfiguration linkerConfig, + Vector objectFiles, Vector sysObjectFiles, + Hashtable compileTargets, VersionInfo versionInfo) { + // + // walk the compile phase targets and + // add those sources that have already been + // assigned to the linker or + // our output files the linker knows how to consume + // files the linker knows how to consume + // + Enumeration compileTargetsEnum = compileTargets.elements(); + while (compileTargetsEnum.hasMoreElements()) { + TargetInfo compileTarget = (TargetInfo) compileTargetsEnum + .nextElement(); + // + // output of compile tasks + // + int bid = linkerConfig.bid(compileTarget.getOutput().toString()); + if (bid > 0) { + objectFiles.addElement(compileTarget.getOutput()); + } + } + File[] objectFileArray = new File[objectFiles.size()]; + objectFiles.copyInto(objectFileArray); + File[] sysObjectFileArray = new File[sysObjectFiles.size()]; + sysObjectFiles.copyInto(sysObjectFileArray); + String baseName = _outfile.getName(); + String[] fullNames = linkerConfig.getOutputFileNames(baseName, versionInfo); + File outputFile = new File(_outfile.getParent(), fullNames[0]); + return new TargetInfo(linkerConfig, objectFileArray, + sysObjectFileArray, outputFile, linkerConfig.getRebuild()); + } + public File getObjdir() { + return _objDir; + } + public File getOutfile() { + return _outfile; + } + + public TargetDef getTargetPlatform() { + return null; + } + /** + * This method collects a Hashtable, keyed by output file name, of + * TargetInfo's for every source file that is specified in the filesets of + * the and nested elements. The TargetInfo's contain the + * appropriate compiler configurations for their possible compilation + * + */ + private Hashtable getTargets(LinkerConfiguration linkerConfig, + Vector objectFiles, VersionInfo versionInfo, File outputFile) { + Hashtable targets = new Hashtable(1000); + TargetDef targetPlatform = getTargetPlatform(); + // + // find active (specialized) compilers + // + Vector biddingProcessors = new Vector(_compilers.size()); + for (int i = 0; i < _compilers.size(); i++) { + CompilerDef currentCompilerDef = (CompilerDef) _compilers + .elementAt(i); + if (currentCompilerDef.isActive()) { + ProcessorConfiguration config = currentCompilerDef + .createConfiguration(this, linkType, compilerDef, + targetPlatform, versionInfo); + // + // see if this processor had a precompile child element + // + PrecompileDef precompileDef = currentCompilerDef + .getActivePrecompile(compilerDef); + ProcessorConfiguration[] localConfigs = new ProcessorConfiguration[]{config}; + // + // if it does then + // + if (precompileDef != null) { + File prototype = precompileDef.getPrototype(); + // + // will throw exceptions if prototype doesn't exist, etc + // + if (!prototype.exists()) { + throw new BuildException("prototype (" + + prototype.toString() + ") does not exist."); + } + if (prototype.isDirectory()) { + throw new BuildException("prototype (" + + prototype.toString() + ") is a directory."); + } + String[] exceptFiles = precompileDef.getExceptFiles(); + // + // create a precompile building and precompile using + // variants of the configuration + // or return null if compiler doesn't support + // precompilation + CompilerConfiguration[] configs = ((CompilerConfiguration) config) + .createPrecompileConfigurations(prototype, + exceptFiles); + if (configs != null && configs.length == 2) { + // + // visit the precompiled file to add it into the + // targets list (just like any other file if + // compiler doesn't support precompilation) + TargetMatcher matcher = new TargetMatcher(this, + _objDir, + new ProcessorConfiguration[]{configs[0]}, + linkerConfig, objectFiles, targets, versionInfo); + + matcher.visit(new File(prototype.getParent()), + prototype.getName()); + // + // only the configuration that uses the + // precompiled header gets added to the bidding list + biddingProcessors.addElement(configs[1]); + localConfigs = new ProcessorConfiguration[2]; + localConfigs[0] = configs[1]; + localConfigs[1] = config; + } + } + // + // if the compiler has a fileset + // then allow it to add its files + // to the set of potential targets + if (currentCompilerDef.hasFileSets()) { + TargetMatcher matcher = new TargetMatcher(this, _objDir, + localConfigs, linkerConfig, objectFiles, targets, + versionInfo); + currentCompilerDef.visitFiles(matcher); + } + biddingProcessors.addElement(config); + } + } + // + // add fallback compiler at the end + // + ProcessorConfiguration config = compilerDef.createConfiguration(this, + linkType, null, targetPlatform, versionInfo); + biddingProcessors.addElement(config); + ProcessorConfiguration[] bidders = new ProcessorConfiguration[biddingProcessors + .size()]; + biddingProcessors.copyInto(bidders); + // + // bid out the 's in the cctask + // + TargetMatcher matcher = new TargetMatcher(this, _objDir, bidders, + linkerConfig, objectFiles, targets, versionInfo); + compilerDef.visitFiles(matcher); + + if (outputFile != null && versionInfo != null) { + boolean isDebug = linkerConfig.isDebug(); + try { + linkerConfig.getLinker().addVersionFiles(versionInfo, linkType, + outputFile, + isDebug, + _objDir, matcher); + } catch(IOException ex) { + throw new BuildException(ex); + } + } + return targets; + } + /** + * Sets the default compiler adapter. Use the "name" attribute when the + * compiler is a supported compiler. + * + * @param classname + * fully qualified classname which implements CompilerAdapter + */ + public void setClassname(String classname) { + compilerDef.setClassname(classname); + linkerDef.setClassname(classname); + } + /** + * Sets the dataset for OS/390 builds. + * + * @param dataset + * The dataset to set + */ + public void setDataset(String dataset) { + this.dataset = dataset; + } + /** + * Enables or disables generation of debug info. + */ + public void setDebug(boolean debug) { + compilerDef.setDebug(debug); + linkerDef.setDebug(debug); + } + + /** + * Gets debug state. + * @return true if building for debugging + */ + public boolean getDebug() { + return compilerDef.getDebug(null, 0); + } + + /** + * Deprecated. + * + * Controls the depth of the dependency evaluation. Used to do a quick + * check of changes before a full build. + * + * Any negative value which will perform full dependency checking. Positive + * values will truncate dependency checking. A value of 0 will cause only + * those files that changed to be recompiled, a value of 1 which cause + * files that changed or that explicitly include a file that changed to be + * recompiled. + * + * Any non-negative value will cause a BuildException to be thrown before + * attempting a link or completing the task. + * + */ + public void setDependencyDepth(int depth) { + dependencyDepth = depth; + } + /** + * Enables generation of exception handling code + */ + public void setExceptions(boolean exceptions) { + compilerDef.setExceptions(exceptions); + } + /** + * Enables run-time type information. + */ + public void setRtti(boolean rtti) { + compilerDef.setRtti(rtti); + } + // public LinkType getLinkType() { + // return linkType; + // } + /** + * Enables or disables incremental linking. + * + * @param incremental + * new state + */ + public void setIncremental(boolean incremental) { + linkerDef.setIncremental(incremental); + } + /** + * Set use of libtool. + * + * If set to true, the "libtool " will be prepended to the command line for + * compatible processors + * + * @param libtool + * If true, use libtool. + */ + public void setLibtool(boolean libtool) { + compilerDef.setLibtool(libtool); + linkerDef.setLibtool(libtool); + } + /** + * Sets the output file type. Supported values "executable", "shared", and + * "static". Deprecated, specify outtype instead. + * + * @deprecated + */ + public void setLink(OutputTypeEnum outputType) { + linkType.setOutputType(outputType); + } + /** + * Enables or disables generation of multithreaded code + * + * @param multi + * If true, generated code may be multithreaded. + */ + public void setMultithreaded(boolean multi) { + compilerDef.setMultithreaded(multi); + } + // + // keep near duplicate comment at CompilerDef.setName in sync + // + /** + * Sets type of the default compiler and linker. + * + * Supported compilers + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
gcc (default)GCC C++ compiler
g++GCC C++ compiler
c++GCC C++ compiler
g77GNU FORTRAN compiler
msvcMicrosoft Visual C++
bccBorland C++ Compiler
msrcMicrosoft Resource Compiler
brcBorland Resource Compiler
dfCompaq Visual Fortran Compiler
midlMicrosoft MIDL Compiler
iclIntel C++ compiler for Windows (IA-32)
eclIntel C++ compiler for Windows (IA-64)
iccIntel C++ compiler for Linux (IA-32)
eccIntel C++ compiler for Linux (IA-64)
CCSun ONE C++ compiler
aCCHP aC++ C++ Compiler
os390OS390 C Compiler
os400Icc Compiler
sunc89Sun C89 C Compiler
xlCVisualAge C Compiler
uicQt user interface compiler (creates .h, .cpp and moc_*.cpp files).
mocQt meta-object compiler
xpidlMozilla xpidl compiler (creates .h and .xpt files).
wclOpenWatcom C/C++ compiler
wflOpenWatcom FORTRAN compiler
+ * + */ + public void setName(CompilerEnum name) { + compilerDef.setName(name); + Processor compiler = compilerDef.getProcessor(); + Linker linker = compiler.getLinker(linkType); + linkerDef.setProcessor(linker); + } + /** + * Do not propagate old environment when new environment variables are + * specified. + */ + public void setNewenvironment(boolean newenv) { + compilerDef.setNewenvironment(newenv); + linkerDef.setNewenvironment(newenv); + } + /** + * Sets the destination directory for object files. + * + * Generally this should be a property expression that evaluates to + * distinct debug and release object file directories. + * + * @param dir + * object directory + */ + public void setObjdir(File dir) { + if (dir == null) { + throw new NullPointerException("dir"); + } + _objDir = dir; + } + /** + * Sets the output file name. If not specified, the task will only compile + * files and not attempt to link. If an extension is not specified, the + * task may use a system appropriate extension and prefix, for example, + * outfile="example" may result in "libexample.so" being created. + * + * @param outfile + * output file name + */ + public void setOutfile(File outfile) { + // + // if file name was empty, skip link step + // + if (outfile == null || outfile.toString().length() > 0) { + _outfile = outfile; + } + } + /** + * Specifies the name of a property to set with the physical filename that + * is produced by the linker + */ + public void setOutputFileProperty(String outputFileProperty) { + this.outputFileProperty = outputFileProperty; + } + /** + * Sets the output file type. Supported values "executable", "shared", and + * "static". + */ + public void setOuttype(OutputTypeEnum outputType) { + linkType.setOutputType(outputType); + } + + /** + * Gets output type. + * @return output type + */ + public String getOuttype() { + return linkType.getOutputType(); + } + + /** + * Sets the project. + */ + public void setProject(Project project) { + super.setProject(project); + compilerDef.setProject(project); + linkerDef.setProject(project); + } + /** + * If set to true, all files will be rebuilt. + * + * @param rebuildAll If true, all files will be rebuilt. If false, up to + * date files will not be rebuilt. + */ + public void setRebuild(boolean rebuildAll) { + compilerDef.setRebuild(rebuildAll); + linkerDef.setRebuild(rebuildAll); + } + /** + * If set to true, compilation errors will not stop the task until all + * files have been attempted. + * + * @param relentless + * If true, don't stop on the first compilation error + * + */ + public void setRelentless(boolean relentless) { + this.relentless = relentless; + } + /** + * Sets the type of runtime library, possible values "dynamic", "static". + */ + public void setRuntime(RuntimeType rtlType) { + linkType.setStaticRuntime((rtlType.getIndex() == 1)); + } + /** + * Sets the nature of the subsystem under which that the program will + * execute. + * + * Supported subsystems + * + * + * + * + * + * + * + * + * + * + * + * + *
guiGraphical User Interface
consoleCommand Line Console
otherOther
+ * + * @param subsystem + * subsystem + * @throws NullPointerException + * if subsystem is null + */ + public void setSubsystem(SubsystemEnum subsystem) { + if (subsystem == null) { + throw new NullPointerException("subsystem"); + } + linkType.setSubsystem(subsystem); + } + + /** + * Gets subsystem name. + * @return Subsystem name + */ + public String getSubsystem() { + return linkType.getSubsystem(); + } + + /** + * Enumerated attribute with the values "none", "severe", "default", + * "production", "diagnostic", and "aserror". + */ + public void setWarnings(WarningLevelEnum level) { + compilerDef.setWarnings(level); + } + + /** + * Indicates whether the build will continue + * even if there are compilation errors; defaults to true. + * @param fail if true halt the build on failure + */ + public void setFailonerror(boolean fail) { + failOnError = fail; + } + + /** + * Gets the failonerror flag. + * @return the failonerror flag + */ + public boolean getFailonerror() { + return failOnError; + } + /** + * Adds a target definition or reference (Non-functional prototype). + * + * @param target + * target + * @throws NullPointerException + * if compiler is null + */ + public void addConfiguredTarget(TargetDef target) { + if (target == null) { + throw new NullPointerException("target"); + } + target.setProject(getProject()); + targetPlatforms.addElement(target); + } + /** + * Adds a distributer definition or reference (Non-functional prototype). + * + * @param distributer + * distributer + * @throws NullPointerException + * if compiler is null + */ + public void addConfiguredDistributer(DistributerDef distributer) { + if (distributer == null) { + throw new NullPointerException("distributer"); + } + distributer.setProject(getProject()); + distributers.addElement(distributer); + } + /** + * Sets optimization. + * @param optimization + */ + public void setOptimize(OptimizationEnum optimization) { + compilerDef.setOptimize(optimization); + } + + /** + * Adds desriptive version information to be included in the + * generated file. The first active version info block will + * be used. + */ + public void addConfiguredVersioninfo(VersionInfo newVersionInfo) { + newVersionInfo.setProject(this.getProject()); + versionInfos.addElement(newVersionInfo); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java b/src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java new file mode 100644 index 0000000..317d6c3 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java @@ -0,0 +1,58 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.IOException; + +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor; +public class CCTaskProgressMonitor implements ProgressMonitor { + private ProcessorConfiguration config; + private TargetHistoryTable history; + private VersionInfo versionInfo; + private long lastCommit = -1; + public CCTaskProgressMonitor(TargetHistoryTable history, VersionInfo versionInfo) { + this.history = history; + this.versionInfo = versionInfo; + } + public void finish(ProcessorConfiguration config, boolean normal) { + long current = System.currentTimeMillis(); + if ((current - lastCommit) > 120000) { + try { + history.commit(); + lastCommit = System.currentTimeMillis(); + } catch (IOException ex) { + } + } + } + public void progress(String[] sources) { + history.update(config, sources, versionInfo); + long current = System.currentTimeMillis(); + if ((current - lastCommit) > 120000) { + try { + history.commit(); + lastCommit = current; + } catch (IOException ex) { + } + } + } + public void start(ProcessorConfiguration config) { + if (lastCommit < 0) { + lastCommit = System.currentTimeMillis(); + } + this.config = config; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java new file mode 100644 index 0000000..512ef37 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CPUEnum.java @@ -0,0 +1,71 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Enumeration of cpu types. + * + * @author Curt Arnold + * + */ +public final class CPUEnum + extends EnumeratedAttribute { + + /** + * Constructor. + * + * Set by default to "pentium3" + * + * @see java.lang.Object#Object() + */ + public CPUEnum() { + setValue("pentium3"); + } + + /** + * Gets list of acceptable values. + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] { + "i386", + "i486", + "i586", + "i686", + "pentium", + "pentium-mmx", + "pentiumpro", + "pentium2", + "pentium3", + "pentium4", + "k6", + "k6-2", + "k6-3", + "athlon", + "athlon-tbird", + "athlon-4", + "athlon-xp", + "athlon-mp", + "winchip-c6", + "winchip2", + "c3" }; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CUtil.java b/src/main/java/net/sf/antcontrib/cpptasks/CUtil.java new file mode 100644 index 0000000..482593e --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CUtil.java @@ -0,0 +1,523 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Execute; +import org.apache.tools.ant.taskdefs.LogStreamHandler; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.Environment; +import org.apache.tools.ant.util.StringUtils; + +/** + * Some utilities used by the CC and Link tasks. + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public class CUtil { + /** + * A class that splits a white-space, comma-separated list into a String + * array. Used for task attributes. + */ + public static final class StringArrayBuilder { + private String[] _value; + public StringArrayBuilder(String value) { + // Split the defines up + StringTokenizer tokens = new StringTokenizer(value, ", "); + Vector vallist = new Vector(); + while (tokens.hasMoreTokens()) { + String val = tokens.nextToken().trim(); + if (val.length() == 0) { + continue; + } + vallist.addElement(val); + } + _value = new String[vallist.size()]; + vallist.copyInto(_value); + } + public String[] getValue() { + return _value; + } + } + /** + * Adds the elements of the array to the given vector + */ + public static void addAll(Vector dest, Object[] src) { + if (src == null) { + return; + } + for (int i = 0; i < src.length; i++) { + dest.addElement(src[i]); + } + } + /** + * Checks a array of names for non existent or non directory entries and + * nulls them out. + * + * @return Count of non-null elements + */ + public static int checkDirectoryArray(String[] names) { + int count = 0; + for (int i = 0; i < names.length; i++) { + if (names[i] != null) { + File dir = new File(names[i]); + if (dir.exists() && dir.isDirectory()) { + count++; + } else { + names[i] = null; + } + } + } + return count; + } + /** + * Extracts the basename of a file, removing the extension, if present + */ + public static String getBasename(File file) { + String path = file.getPath(); + // Remove the extension + String basename = file.getName(); + int pos = basename.lastIndexOf('.'); + if (pos != -1) { + basename = basename.substring(0, pos); + } + return basename; + } + /** + * Gets the parent directory for the executable file name using the current + * directory and system executable path + * + * @param exeName + * Name of executable such as "cl.exe" + * @return parent directory or null if not located + */ + public static File getExecutableLocation(String exeName) { + // + // must add current working directory to the + // from of the path from the "path" environment variable + File currentDir = new File(System.getProperty("user.dir")); + if (new File(currentDir, exeName).exists()) { + return currentDir; + } + File[] envPath = CUtil.getPathFromEnvironment("PATH", + File.pathSeparator); + for (int i = 0; i < envPath.length; i++) { + if (new File(envPath[i], exeName).exists()) { + return envPath[i]; + } + } + return null; + } + /** + * Extracts the parent of a file + */ + public static String getParentPath(String path) { + int pos = path.lastIndexOf(File.separator); + if (pos <= 0) { + return null; + } + return path.substring(0, pos); + } + /** + * Returns an array of File for each existing directory in the specified + * environment variable + * + * @param envVariable + * environment variable name such as "LIB" or "INCLUDE" + * @param delim + * delimitor used to separate parts of the path, typically ";" + * or ":" + * @return array of File's for each part that is an existing directory + */ + public static File[] getPathFromEnvironment(String envVariable, String delim) { + // OS/4000 does not support the env command. + if (System.getProperty("os.name").equals("OS/400")) + return new File[]{}; + Vector osEnv = Execute.getProcEnvironment(); + String match = envVariable.concat("="); + for (Enumeration e = osEnv.elements(); e.hasMoreElements();) { + String entry = ((String) e.nextElement()).trim(); + if (entry.length() > match.length()) { + String entryFrag = entry.substring(0, match.length()); + if (entryFrag.equalsIgnoreCase(match)) { + String path = entry.substring(match.length()); + return parsePath(path, delim); + } + } + } + File[] noPath = new File[0]; + return noPath; + } + /** + * Returns a relative path for the targetFile relative to the base + * directory. + * + * @param base + * base directory as returned by File.getCanonicalPath() + * @param targetFile + * target file + * @return relative path of target file. Returns targetFile if there were + * no commonalities between the base and the target + * + */ + public static String getRelativePath(final String base, final File targetFile) { + try { + // + // remove trailing file separator + // + String canonicalBase = base; + if (base.charAt(base.length() - 1) != File.separatorChar) { + canonicalBase = base + File.separatorChar; + } + // + // get canonical name of target + // + String canonicalTarget; + if (System.getProperty("os.name").equals("OS/400")) + canonicalTarget = targetFile.getPath(); + else + canonicalTarget = targetFile.getCanonicalPath(); + if (canonicalBase.startsWith(canonicalTarget + File.separatorChar)) { + canonicalTarget = canonicalTarget + File.separator; + } + if (canonicalTarget.equals(canonicalBase)) { + return "."; + } + // + // see if the prefixes are the same + // + if (canonicalBase.substring(0, 2).equals("\\\\")) { + // + // UNC file name, if target file doesn't also start with same + // server name, don't go there + int endPrefix = canonicalBase.indexOf('\\', 2); + String prefix1 = canonicalBase.substring(0, endPrefix); + String prefix2 = canonicalTarget.substring(0, endPrefix); + if (!prefix1.equals(prefix2)) { + return canonicalTarget; + } + } else { + if (canonicalBase.substring(1, 3).equals(":\\")) { + int endPrefix = 2; + String prefix1 = canonicalBase.substring(0, endPrefix); + String prefix2 = canonicalTarget.substring(0, endPrefix); + if (!prefix1.equals(prefix2)) { + return canonicalTarget; + } + } else { + if (canonicalBase.charAt(0) == '/') { + if (canonicalTarget.charAt(0) != '/') { + return canonicalTarget; + } + } + } + } + char separator = File.separatorChar; + int lastCommonSeparator = -1; + int minLength = canonicalBase.length(); + if (canonicalTarget.length() < minLength) { + minLength = canonicalTarget.length(); + } + // + // walk to the shorter of the two paths + // finding the last separator they have in common + for (int i = 0; i < minLength; i++) { + if (canonicalTarget.charAt(i) == canonicalBase.charAt(i)) { + if (canonicalTarget.charAt(i) == separator) { + lastCommonSeparator = i; + } + } else { + break; + } + } + StringBuffer relativePath = new StringBuffer(50); + // + // walk from the first difference to the end of the base + // adding "../" for each separator encountered + // + for (int i = lastCommonSeparator + 1; i < canonicalBase.length(); i++) { + if (canonicalBase.charAt(i) == separator) { + if (relativePath.length() > 0) { + relativePath.append(separator); + } + relativePath.append(".."); + } + } + if (canonicalTarget.length() > lastCommonSeparator + 1) { + if (relativePath.length() > 0) { + relativePath.append(separator); + } + relativePath.append(canonicalTarget.substring(lastCommonSeparator + 1)); + } + return relativePath.toString(); + } catch (IOException ex) { + } + return targetFile.toString(); + } + public static boolean isActive(Project p, String ifCond, String unlessCond) + throws BuildException { + if (ifCond != null) { + String ifValue = p.getProperty(ifCond); + if (ifValue == null) { + return false; + } else { + if (ifValue.equals("false") || ifValue.equals("no")) { + throw new BuildException("if condition \"" + ifCond + + "\" has suspicious value \"" + ifValue); + } + } + } + if (unlessCond != null) { + String unlessValue = p.getProperty(unlessCond); + if (unlessValue != null) { + if (unlessValue.equals("false") || unlessValue.equals("no")) { + throw new BuildException("unless condition \"" + unlessCond + + "\" has suspicious value \"" + unlessValue); + } + return false; + } + } + return true; + } + /** + * Parse a string containing directories into an File[] + * + * @param path + * path string, for example ".;c:\something\include" + * @param delim + * delimiter, typically ; or : + */ + public static File[] parsePath(String path, String delim) { + Vector libpaths = new Vector(); + int delimPos = 0; + for (int startPos = 0; startPos < path.length(); startPos = delimPos + + delim.length()) { + delimPos = path.indexOf(delim, startPos); + if (delimPos < 0) { + delimPos = path.length(); + } + // + // don't add an entry for zero-length paths + // + if (delimPos > startPos) { + String dirName = path.substring(startPos, delimPos); + File dir = new File(dirName); + if (dir.exists() && dir.isDirectory()) { + libpaths.addElement(dir); + } + } + } + File[] paths = new File[libpaths.size()]; + libpaths.copyInto(paths); + return paths; + } + /** + * This method is exposed so test classes can overload and test the + * arguments without actually spawning the compiler + */ + public static int runCommand(CCTask task, File workingDir, + String[] cmdline, boolean newEnvironment, Environment env) + throws BuildException { + try { + task.log(Commandline.toString(cmdline), Project.MSG_VERBOSE); + Execute exe = new Execute(new LogStreamHandler(task, + Project.MSG_INFO, Project.MSG_ERR)); + if (System.getProperty("os.name").equals("OS/390")) + exe.setVMLauncher(false); + exe.setAntRun(task.getProject()); + exe.setCommandline(cmdline); + exe.setWorkingDirectory(workingDir); + if (env != null) { + String[] environment = env.getVariables(); + if (environment != null) { + for (int i = 0; i < environment.length; i++) { + task.log("Setting environment variable: " + + environment[i], Project.MSG_VERBOSE); + } + } + exe.setEnvironment(environment); + } + exe.setNewenvironment(newEnvironment); + return exe.execute(); + } catch (java.io.IOException exc) { + throw new BuildException("Could not launch " + cmdline[0] + ": " + + exc, task.getLocation()); + } + } + /** + * Compares the contents of 2 arrays for equaliy. + */ + public static boolean sameList(Object[] a, Object[] b) { + if (a == null || b == null || a.length != b.length) { + return false; + } + for (int i = 0; i < a.length; i++) { + if (!a[i].equals(b[i])) { + return false; + } + } + return true; + } + /** + * Compares the contents of an array and a Vector for equality. + */ + public static boolean sameList(Vector v, Object[] a) { + if (v == null || a == null || v.size() != a.length) { + return false; + } + for (int i = 0; i < a.length; i++) { + Object o = a[i]; + if (!o.equals(v.elementAt(i))) { + return false; + } + } + return true; + } + /** + * Compares the contents of an array and a Vector for set equality. Assumes + * input array and vector are sets (i.e. no duplicate entries) + */ + public static boolean sameSet(Object[] a, Vector b) { + if (a == null || b == null || a.length != b.size()) { + return false; + } + if (a.length == 0) { + return true; + } + // Convert the array into a set + Hashtable t = new Hashtable(); + for (int i = 0; i < a.length; i++) { + t.put(a[i], a[i]); + } + for (int i = 0; i < b.size(); i++) { + Object o = b.elementAt(i); + if (t.remove(o) == null) { + return false; + } + } + return (t.size() == 0); + } + /** + * Converts a vector to a string array. + */ + public static String[] toArray(Vector src) { + String[] retval = new String[src.size()]; + src.copyInto(retval); + return retval; + } + /** + * Replaces any embedded quotes in the string so that the value can be + * placed in an attribute in an XML file + * + * @param attrValue + * value to be expressed + * @return equivalent attribute literal + * + */ + public static String xmlAttribEncode(String attrValue) { + StringBuffer buf = new StringBuffer (attrValue); + int quotePos; + + for (quotePos = -1; (quotePos = buf.indexOf("\"", quotePos + 1)) >= 0;) { + buf.deleteCharAt(quotePos); + buf.insert (quotePos, """); + quotePos += 5; + } + + for (quotePos = -1; (quotePos = buf.indexOf("<", quotePos + 1)) >= 0;) { + buf.deleteCharAt(quotePos); + buf.insert (quotePos, "<"); + quotePos += 3; + } + + for (quotePos = -1; (quotePos = buf.indexOf(">", quotePos + 1)) >= 0;) { + buf.deleteCharAt(quotePos); + buf.insert (quotePos, ">"); + quotePos += 3; + } + + return buf.toString(); + } + + public final static int FILETIME_EPSILON = 500; + /** + * Determines whether time1 is earlier than time2 + * to a degree that file system time truncation is not significant. + * + * @param time1 long first time value + * @param time2 long second time value + * @return boolean if first time value is earlier than second time value. + * If the values are within the rounding error of the file system return false. + */ + public static boolean isSignificantlyBefore(long time1, long time2) { + return (time1 + FILETIME_EPSILON) < time2; + } + /** + * Determines whether time1 is later than time2 + * to a degree that file system time truncation is not significant. + * + * @param time1 long first time value + * @param time2 long second time value + * @return boolean if first time value is later than second time value. + * If the values are within the rounding error of the file system return false. + */ + public static boolean isSignificantlyAfter(long time1, long time2) { + return time1 > (time2 + FILETIME_EPSILON); + } + + + public static String toWindowsPath(final String path) { + if (File.separatorChar != '\\' && path.indexOf(File.separatorChar) != -1) { + return StringUtils.replace(path, File.separator, "\\"); + } + return path; + } + + public static String toUnixPath(final String path) { + if (File.separatorChar != '/' && path.indexOf(File.separatorChar) != -1) { + return StringUtils.replace(path, File.separator, "/"); + } + return path; + } + + /** + * Determines if source file has a system path, + * that is part of the compiler or platform. + * @param source source, may not be null. + * @return true is source file appears to be system library + * and its path should be discarded. + */ + public static boolean isSystemPath(final File source) { + String lcPath = source.getAbsolutePath().toLowerCase(java.util.Locale.US); + return lcPath.indexOf("platformsdk") != -1 + || lcPath.indexOf("microsoft") != -1 || + lcPath == "/usr/include" || + lcPath == "/usr/lib" || + lcPath == "/usr/local/include" || + lcPath == "/usr/local/lib"; + } + + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java b/src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java new file mode 100644 index 0000000..313d3ac --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CompilerDef.java @@ -0,0 +1,502 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.util.Enumeration; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.Compiler; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; +import net.sf.antcontrib.cpptasks.types.CompilerArgument; +import net.sf.antcontrib.cpptasks.types.ConditionalPath; +import net.sf.antcontrib.cpptasks.types.DefineSet; +import net.sf.antcontrib.cpptasks.types.IncludePath; +import net.sf.antcontrib.cpptasks.types.SystemIncludePath; +import net.sf.antcontrib.cpptasks.types.UndefineArgument; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +/** + * A compiler definition. compiler elements may be placed either as children of + * a cc element or the project element. A compiler element with an id attribute + * may be referenced from compiler elements with refid or extends attributes. + * + * @author Adam Murdoch + */ +public final class CompilerDef extends ProcessorDef { + /** The source file sets. */ + private final Vector defineSets = new Vector(); + private Boolean exceptions; + private Boolean rtti; + private final Vector includePaths = new Vector(); + private Boolean multithreaded; + private final Vector precompileDefs = new Vector(); + private final Vector sysIncludePaths = new Vector(); + private OptimizationEnum optimization; + private int warnings = -1; + public CompilerDef() { + } + /** + * Adds a compiler command-line arg. + */ + public void addConfiguredCompilerArg(CompilerArgument arg) { + if (isReference()) { + throw noChildrenAllowed(); + } + addConfiguredProcessorArg(arg); + } + /** + * Adds a compiler command-line arg. + */ + public void addConfiguredCompilerParam(CompilerParam param) { + if (isReference()) { + throw noChildrenAllowed(); + } + addConfiguredProcessorParam(param); + } + /** + * Adds a defineset. + */ + public void addConfiguredDefineset(DefineSet defs) { + if (defs == null) { + throw new NullPointerException("defs"); + } + if (isReference()) { + throw noChildrenAllowed(); + } + defineSets.addElement(defs); + } + /** + * Creates an include path. + */ + public IncludePath createIncludePath() { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project must be set"); + } + if (isReference()) { + throw noChildrenAllowed(); + } + IncludePath path = new IncludePath(p); + includePaths.addElement(path); + return path; + } + /** + * Specifies precompilation prototype file and exclusions. + * + */ + public PrecompileDef createPrecompile() throws BuildException { + Project p = getProject(); + if (isReference()) { + throw noChildrenAllowed(); + } + PrecompileDef precomp = new PrecompileDef(); + precomp.setProject(p); + precompileDefs.addElement(precomp); + return precomp; + } + /** + * Creates a system include path. Locations and timestamps of files located + * using the system include paths are not used in dependency analysis. + * + * + * Standard include locations should not be specified. The compiler + * adapters should recognized the settings from the appropriate environment + * variables or configuration files. + */ + public SystemIncludePath createSysIncludePath() { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project must be set"); + } + if (isReference()) { + throw noChildrenAllowed(); + } + SystemIncludePath path = new SystemIncludePath(p); + sysIncludePaths.addElement(path); + return path; + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + public UndefineArgument[] getActiveDefines() { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException( + "project must be set before this call"); + } + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getActiveDefines(); + } + Vector actives = new Vector(); + for (int i = 0; i < defineSets.size(); i++) { + DefineSet currentSet = (DefineSet) defineSets.elementAt(i); + UndefineArgument[] defines = currentSet.getDefines(); + for (int j = 0; j < defines.length; j++) { + if (defines[j].isActive(p)) { + actives.addElement(defines[j]); + } + } + } + UndefineArgument[] retval = new UndefineArgument[actives.size()]; + actives.copyInto(retval); + return retval; + } + /** + * Returns the compiler-specific include path. + */ + public String[] getActiveIncludePaths() { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getActiveIncludePaths(); + } + return getActivePaths(includePaths); + } + private String[] getActivePaths(Vector paths) { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project not set"); + } + Vector activePaths = new Vector(paths.size()); + for (int i = 0; i < paths.size(); i++) { + ConditionalPath path = (ConditionalPath) paths.elementAt(i); + if (path.isActive(p)) { + String[] pathEntries = path.list(); + for (int j = 0; j < pathEntries.length; j++) { + activePaths.addElement(pathEntries[j]); + } + } + } + String[] pathNames = new String[activePaths.size()]; + activePaths.copyInto(pathNames); + return pathNames; + } + public PrecompileDef getActivePrecompile(CompilerDef ccElement) { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getActivePrecompile(ccElement); + } + PrecompileDef current = null; + Enumeration iter = precompileDefs.elements(); + while (iter.hasMoreElements()) { + current = (PrecompileDef) iter.nextElement(); + if (current.isActive()) { + return current; + } + } + CompilerDef extendedDef = (CompilerDef) getExtends(); + if (extendedDef != null) { + current = extendedDef.getActivePrecompile(null); + if (current != null) { + return current; + } + } + if (ccElement != null && getInherit()) { + return ccElement.getActivePrecompile(null); + } + return null; + } + public String[] getActiveSysIncludePaths() { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getActiveSysIncludePaths(); + } + return getActivePaths(sysIncludePaths); + } + public final boolean getExceptions(CompilerDef[] defaultProviders, int index) { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getExceptions(defaultProviders, index); + } + if (exceptions != null) { + return exceptions.booleanValue(); + } else { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getExceptions(defaultProviders, + index + 1); + } + } + return false; + } + public final Boolean getRtti(CompilerDef[] defaultProviders, int index) { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getRtti(defaultProviders, index); + } + if (rtti != null) { + return rtti; + } else { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getRtti(defaultProviders, + index + 1); + } + } + return null; + } + public final OptimizationEnum getOptimization(CompilerDef[] defaultProviders, int index) { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getOptimization(defaultProviders, index); + } + if (optimization != null) { + return optimization; + } else { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getOptimization(defaultProviders, + index + 1); + } + } + return null; + } + + public boolean getMultithreaded(CompilerDef[] defaultProviders, int index) { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getMultithreaded(defaultProviders, index); + } + if (multithreaded != null) { + return multithreaded.booleanValue(); + } else { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getMultithreaded( + defaultProviders, index + 1); + } + } + return true; + } + public Processor getProcessor() { + Processor processor = super.getProcessor(); + if (processor == null) { + processor = GccCCompiler.getInstance(); + } + if (getLibtool() && processor instanceof CommandLineCompiler) { + CommandLineCompiler compiler = (CommandLineCompiler) processor; + processor = compiler.getLibtoolCompiler(); + } + return processor; + } + public int getWarnings(CompilerDef[] defaultProviders, int index) { + if (isReference()) { + return ((CompilerDef) getCheckedRef(CompilerDef.class, + "CompilerDef")).getWarnings(defaultProviders, index); + } + if (warnings == -1) { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getWarnings(defaultProviders, + index + 1); + } + } + return warnings; + } + /** + * Sets the default compiler adapter. Use the "name" attribute when the + * compiler is a supported compiler. + * + * @param classname + * fully qualified classname which implements CompilerAdapter + */ + public void setClassname(String classname) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + super.setClassname(classname); + Processor proc = getProcessor(); + if (!(proc instanceof Compiler)) { + throw new BuildException(classname + " does not implement Compiler"); + } + } + /** + * Enables or disables exception support. + * + * @param exceptions + * if true, exceptions are supported. + * + */ + public void setExceptions(boolean exceptions) { + if (isReference()) { + throw tooManyAttributes(); + } + this.exceptions = booleanValueOf(exceptions); + } + + /** + * Enables or disables run-time type information. + * + * @param rtti + * if true, run-time type information is supported. + * + */ + public void setRtti(boolean rtti) { + if (isReference()) { + throw tooManyAttributes(); + } + this.rtti = booleanValueOf(rtti); + } + + /** + * Enables or disables generation of multithreaded code. Unless specified, + * multithreaded code generation is enabled. + * + * @param multithreaded + * If true, generated code may be multithreaded. + */ + public void setMultithreaded(boolean multithreaded) { + if (isReference()) { + throw tooManyAttributes(); + } + this.multithreaded = booleanValueOf(multithreaded); + } + /** + * Sets compiler type. + * + * + * Supported compilers + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
gcc (default)GCC C++ compiler
g++GCC C++ compiler
c++GCC C++ compiler
g77GNU Fortran compiler
msvcMicrosoft Visual C++
bccBorland C++ Compiler
msrcMicrosoft Resource Compiler
brcBorland Resource Compiler
dfCompaq Visual Fortran Compiler
midlMicrosoft MIDL Compiler
iclIntel C++ compiler for Windows (IA-32)
eclIntel C++ compiler for Windows (IA-64)
iccIntel C++ compiler for Linux (IA-32)
eccIntel C++ compiler for Linux (IA-64)
CCSun ONE C++ compiler
aCCHP aC++ C++ Compiler
os390OS390 C Compiler
os400Icc Compiler
sunc89Sun C89 C Compiler
xlCVisualAge C Compiler
uicQt user interface compiler
mocQt meta-object compiler
wclOpenWatcom C/C++ compiler
wflOpenWatcom FORTRAN compiler
+ * + */ + public void setName(CompilerEnum name) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + Compiler compiler = name.getCompiler(); + setProcessor(compiler); + } + protected void setProcessor(Processor proc) throws BuildException { + try { + super.setProcessor((Compiler) proc); + } catch (ClassCastException ex) { + throw new BuildException(ex); + } + } + /** + * Enumerated attribute with the values "none", "severe", "default", + * "production", "diagnostic", and "aserror". + */ + public void setWarnings(WarningLevelEnum level) { + warnings = level.getIndex(); + } + /** + * Sets optimization level. + * + * @param value optimization level + */ + public void setOptimize(OptimizationEnum value) { + if (isReference()) { + throw tooManyAttributes(); + } + this.optimization = value; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java new file mode 100644 index 0000000..0233050 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CompilerEnum.java @@ -0,0 +1,262 @@ +/* + * + * Copyright 2002-2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import net.sf.antcontrib.cpptasks.arm.ADSCCompiler; +import net.sf.antcontrib.cpptasks.borland.BorlandCCompiler; +import net.sf.antcontrib.cpptasks.borland.BorlandResourceCompiler; +import net.sf.antcontrib.cpptasks.compaq.CompaqVisualFortranCompiler; +import net.sf.antcontrib.cpptasks.compiler.Compiler; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCCompiler; +import net.sf.antcontrib.cpptasks.devstudio.DevStudio2005CCompiler; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioMIDLCompiler; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioResourceCompiler; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; +import net.sf.antcontrib.cpptasks.gcc.WindresResourceCompiler; +import net.sf.antcontrib.cpptasks.hp.aCCCompiler; +import net.sf.antcontrib.cpptasks.ibm.VisualAgeCCompiler; +import net.sf.antcontrib.cpptasks.intel.IntelLinux32CCompiler; +import net.sf.antcontrib.cpptasks.intel.IntelLinux64CCompiler; +import net.sf.antcontrib.cpptasks.intel.IntelWin32CCompiler; +import net.sf.antcontrib.cpptasks.intel.IntelWin64CCompiler; +import net.sf.antcontrib.cpptasks.mozilla.XpidlCompiler; +import net.sf.antcontrib.cpptasks.os390.OS390CCompiler; +import net.sf.antcontrib.cpptasks.os400.IccCompiler; +import net.sf.antcontrib.cpptasks.sun.C89CCompiler; +import net.sf.antcontrib.cpptasks.sun.ForteCCCompiler; +import net.sf.antcontrib.cpptasks.ti.ClxxCCompiler; +import net.sf.antcontrib.cpptasks.trolltech.MetaObjectCompiler; +import net.sf.antcontrib.cpptasks.trolltech.UserInterfaceCompiler; +import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomCCompiler; +import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomFortranCompiler; + +import org.apache.tools.ant.types.EnumeratedAttribute; +/** + * Enumeration of supported compilers + * + * Supported compilers + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
gcc (default)GCC C++ compiler
g++GCC C++ compiler
c++GCC C++ compiler
g77GNU FORTRAN compiler
msvcMicrosoft Visual C++
msvc8Microsoft Visual C++ 8
bccBorland C++ Compiler
msrcMicrosoft Resource Compiler
brcBorland Resource Compiler
dfCompaq Visual Fortran Compiler
midlMicrosoft MIDL Compiler
iclIntel C++ compiler for Windows (IA-32)
eclIntel C++ compiler for Windows (IA-64)
iccIntel C++ compiler for Linux (IA-32)
eccIntel C++ compiler for Linux (IA-64)
CCSun ONE C++ compiler
aCCHP aC++ C++ Compiler
os390OS390 C Compiler
os400Icc Compiler
sunc89Sun C89 C Compiler
xlCVisualAge C Compiler
cl6xTI TMS320C6000 Optimizing Compiler
cl55TI TMS320C55x Optimizing C/C++ Compiler
armcppARM 32-bit C++ compiler
armccARM 32-bit C compiler
tcppARM 16-bit C++ compiler
tccARM 16-bit C compiler
uicQt user interface compiler
mocQt meta-object compiler
xpidlMozilla xpidl compiler (creates .h and .xpt files).
wclOpenWatcom C/C++ compiler (experimental)
wflOpenWatcom FORTRAN compiler (experimental)
windresGNU windres resource compiler
+ * + * @author Curt Arnold + * + */ +public class CompilerEnum extends EnumeratedAttribute { + private final static ProcessorEnumValue[] compilers = new ProcessorEnumValue[]{ + new ProcessorEnumValue("gcc", GccCCompiler.getInstance()), + new ProcessorEnumValue("g++", GccCCompiler.getGppInstance()), + new ProcessorEnumValue("c++", GccCCompiler.getCppInstance()), + new ProcessorEnumValue("g77", GccCCompiler.getG77Instance()), + new ProcessorEnumValue("msvc", DevStudioCCompiler.getInstance()), + new ProcessorEnumValue("msvc8", DevStudio2005CCompiler.getInstance()), + new ProcessorEnumValue("bcc", BorlandCCompiler.getInstance()), + new ProcessorEnumValue("msrc", DevStudioResourceCompiler + .getInstance()), + new ProcessorEnumValue("brc", BorlandResourceCompiler.getInstance()), + new ProcessorEnumValue("df", CompaqVisualFortranCompiler + .getInstance()), + new ProcessorEnumValue("midl", DevStudioMIDLCompiler.getInstance()), + new ProcessorEnumValue("icl", IntelWin32CCompiler.getInstance()), + new ProcessorEnumValue("ecl", IntelWin64CCompiler.getInstance()), + new ProcessorEnumValue("icc", IntelLinux32CCompiler.getInstance()), + new ProcessorEnumValue("ecc", IntelLinux64CCompiler.getInstance()), + new ProcessorEnumValue("CC", ForteCCCompiler.getInstance()), + new ProcessorEnumValue("aCC", aCCCompiler.getInstance()), + new ProcessorEnumValue("os390", OS390CCompiler.getInstance()), + new ProcessorEnumValue("os400", IccCompiler.getInstance()), + new ProcessorEnumValue("sunc89", C89CCompiler.getInstance()), + new ProcessorEnumValue("xlC", VisualAgeCCompiler.getInstance()), + new ProcessorEnumValue("cl6x", ClxxCCompiler.getCl6xInstance()), + new ProcessorEnumValue("cl55", ClxxCCompiler.getCl55Instance()), + new ProcessorEnumValue("armcc", ADSCCompiler.getArmCC()), + new ProcessorEnumValue("armcpp", ADSCCompiler.getArmCpp()), + new ProcessorEnumValue("tcc", ADSCCompiler.getThumbCC()), + new ProcessorEnumValue("tcpp", ADSCCompiler.getThumbCpp()), + // GCC Cross Compilers + new ProcessorEnumValue( + "sparc-sun-solaris2-gcc", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler + .getInstance()), + new ProcessorEnumValue( + "sparc-sun-solaris2-g++", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler + .getGppInstance()), + new ProcessorEnumValue( + "sparc-sun-solaris2-c++", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler + .getCppInstance()), + new ProcessorEnumValue( + "sparc-sun-solaris2-g77", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler + .getG77Instance()), + // GCC Cross Compilers + new ProcessorEnumValue("gcc-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler + .getInstance()), + new ProcessorEnumValue("g++-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler + .getGppInstance()), + new ProcessorEnumValue("c++-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler + .getCppInstance()), + new ProcessorEnumValue("g77-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler + .getG77Instance()), + new ProcessorEnumValue("uic", UserInterfaceCompiler.getInstance()), + new ProcessorEnumValue("moc", MetaObjectCompiler.getInstance()), + new ProcessorEnumValue("xpidl", XpidlCompiler.getInstance()), + new ProcessorEnumValue("wcl", OpenWatcomCCompiler.getInstance()), + new ProcessorEnumValue("wfl", OpenWatcomFortranCompiler.getInstance()), + new ProcessorEnumValue("windres", WindresResourceCompiler.getInstance()) + }; + public Compiler getCompiler() { + return (Compiler) compilers[getIndex()].getProcessor(); + } + public String[] getValues() { + return ProcessorEnumValue.getValues(compilers); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java b/src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java new file mode 100644 index 0000000..8a15a77 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/CompilerParam.java @@ -0,0 +1,33 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +/******************************************************************************* + * Place class description here. + * + * @author inger + * @author + * + * @since + ******************************************************************************/ +public class CompilerParam extends ProcessorParam { + public CompilerParam() { + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java b/src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java new file mode 100644 index 0000000..a04105f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/DependencyInfo.java @@ -0,0 +1,86 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.util.Vector; +/** + * @author Curt Arnold + */ +public final class DependencyInfo { + /** + * Last modified time of this file or anything that it depends on. + * + * Not persisted since almost any change could invalidate it. Initialized + * to long.MIN_VALUE on construction. + */ + private long compositeLastModified; + private/* final */String includePathIdentifier; + private/* final */String[] includes; + private/* final */String source; + private/* final */long sourceLastModified; + private/* final */String[] sysIncludes; + public DependencyInfo(String includePathIdentifier, String source, + long sourceLastModified, Vector includes, Vector sysIncludes) { + if (source == null) { + throw new NullPointerException("source"); + } + if (includePathIdentifier == null) { + throw new NullPointerException("includePathIdentifier"); + } + this.source = source; + this.sourceLastModified = sourceLastModified; + this.includePathIdentifier = includePathIdentifier; + this.includes = new String[includes.size()]; + if (includes.size() == 0) { + compositeLastModified = sourceLastModified; + } else { + includes.copyInto(this.includes); + compositeLastModified = Long.MIN_VALUE; + } + this.sysIncludes = new String[sysIncludes.size()]; + sysIncludes.copyInto(this.sysIncludes); + } + /** + * Returns the latest modification date of the source or anything that it + * depends on. + * + * @return the composite lastModified time, returns Long.MIN_VALUE if not + * set + */ + public long getCompositeLastModified() { + return compositeLastModified; + } + public String getIncludePathIdentifier() { + return includePathIdentifier; + } + public String[] getIncludes() { + String[] includesClone = (String[]) includes.clone(); + return includesClone; + } + public String getSource() { + return source; + } + public long getSourceLastModified() { + return sourceLastModified; + } + public String[] getSysIncludes() { + String[] sysIncludesClone = (String[]) sysIncludes.clone(); + return sysIncludesClone; + } + public void setCompositeLastModified(long lastMod) { + compositeLastModified = lastMod; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java b/src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java new file mode 100644 index 0000000..48a7278 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/DependencyTable.java @@ -0,0 +1,610 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; +/** + * @author Curt Arnold + */ +public final class DependencyTable { + /** + * This class handles populates the TargetHistory hashtable in response to + * SAX parse events + */ + private class DependencyTableHandler extends DefaultHandler { + private File baseDir; + private final DependencyTable dependencyTable; + private String includePath; + private Vector includes; + private String source; + private long sourceLastModified; + private Vector sysIncludes; + /** + * Constructor + * + * @param history + * hashtable of TargetHistory keyed by output name + * @param outputFiles + * existing files in output directory + */ + private DependencyTableHandler(DependencyTable dependencyTable, + File baseDir) { + this.dependencyTable = dependencyTable; + this.baseDir = baseDir; + includes = new Vector(); + sysIncludes = new Vector(); + source = null; + } + public void endElement(String namespaceURI, String localName, + String qName) throws SAXException { + // + // if then + // create Dependency object and add to hashtable + // if corresponding source file exists and + // has the same timestamp + // + if (qName.equals("source")) { + if (source != null && includePath != null) { + File existingFile = new File(baseDir, source); + // + // if the file exists and the time stamp is right + // preserve the dependency info + if (existingFile.exists()) { + // + // would have expected exact matches + // but was seeing some unexpected difference by + // a few tens of milliseconds, as long + // as the times are within a second + long existingLastModified = existingFile.lastModified(); + if (!CUtil.isSignificantlyAfter(existingLastModified, sourceLastModified) && + !CUtil.isSignificantlyBefore(existingLastModified, sourceLastModified)) { + DependencyInfo dependInfo = new DependencyInfo( + includePath, source, sourceLastModified, + includes, sysIncludes); + dependencyTable.putDependencyInfo(source, + dependInfo); + } + } + source = null; + includes.setSize(0); + } + } else { + // + // this causes any elements outside the + // scope of an to be discarded + // + if (qName.equals("includePath")) { + includePath = null; + } + } + } + /** + * startElement handler + */ + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) throws SAXException { + // + // if includes, then add relative file name to vector + // + if (qName.equals("include")) { + includes.addElement(atts.getValue("file")); + } else { + if (qName.equals("sysinclude")) { + sysIncludes.addElement(atts.getValue("file")); + } else { + // + // if source then + // capture source file name, + // modification time and reset includes vector + // + if (qName.equals("source")) { + source = atts.getValue("file"); + sourceLastModified = Long.parseLong(atts + .getValue("lastModified"), 16); + includes.setSize(0); + sysIncludes.setSize(0); + } else { + if (qName.equals("includePath")) { + includePath = atts.getValue("signature"); + } + } + } + } + } + } + public abstract class DependencyVisitor { + /** + * Previews all the children of this source file. + * + * May be called multiple times as DependencyInfo's for children are + * filled in. + * + * @return true to continue towards recursion into included files + */ + public abstract boolean preview(DependencyInfo parent, + DependencyInfo[] children); + /** + * Called if the dependency depth exhausted the stack. + */ + public abstract void stackExhausted(); + /** + * Visits the dependency info. + * + * @return true to continue towards recursion into included files + */ + public abstract boolean visit(DependencyInfo dependInfo); + } + public class TimestampChecker extends DependencyVisitor { + private boolean noNeedToRebuild; + private long outputLastModified; + private boolean rebuildOnStackExhaustion; + public TimestampChecker(final long outputLastModified, + boolean rebuildOnStackExhaustion) { + this.outputLastModified = outputLastModified; + noNeedToRebuild = true; + this.rebuildOnStackExhaustion = rebuildOnStackExhaustion; + } + public boolean getMustRebuild() { + return !noNeedToRebuild; + } + public boolean preview(DependencyInfo parent, DependencyInfo[] children) { + int withCompositeTimes = 0; + long parentCompositeLastModified = parent.getSourceLastModified(); + for (int i = 0; i < children.length; i++) { + if (children[i] != null) { + // + // expedient way to determine if a child forces us to + // rebuild + // + visit(children[i]); + long childCompositeLastModified = children[i] + .getCompositeLastModified(); + if (childCompositeLastModified != Long.MIN_VALUE) { + withCompositeTimes++; + if (childCompositeLastModified > parentCompositeLastModified) { + parentCompositeLastModified = childCompositeLastModified; + } + } + } + } + if (withCompositeTimes == children.length) { + parent.setCompositeLastModified(parentCompositeLastModified); + } + // + // may have been changed by an earlier call to visit() + // + return noNeedToRebuild; + } + public void stackExhausted() { + if (rebuildOnStackExhaustion) { + noNeedToRebuild = false; + } + } + public boolean visit(DependencyInfo dependInfo) { + if (noNeedToRebuild) { + if (CUtil.isSignificantlyAfter(dependInfo.getSourceLastModified(), outputLastModified) + || CUtil.isSignificantlyAfter(dependInfo.getCompositeLastModified(), outputLastModified)) { + noNeedToRebuild = false; + } + } + // + // only need to process the children if + // it has not yet been determined whether + // we need to rebuild and the composite modified time + // has not been determined for this file + return noNeedToRebuild + && dependInfo.getCompositeLastModified() == Long.MIN_VALUE; + } + } + private/* final */File baseDir; + private String baseDirPath; + /** + * a hashtable of DependencyInfo[] keyed by output file name + */ + private final Hashtable dependencies = new Hashtable(); + /** The file the cache was loaded from. */ + private/* final */File dependenciesFile; + /** Flag indicating whether the cache should be written back to file. */ + private boolean dirty; + /** + * Creates a target history table from dependencies.xml in the prject + * directory, if it exists. Otherwise, initializes the dependencies empty. + * + * @param baseDir + * output directory for task + */ + public DependencyTable(File baseDir) { + if (baseDir == null) { + throw new NullPointerException("baseDir"); + } + this.baseDir = baseDir; + try { + baseDirPath = baseDir.getCanonicalPath(); + } catch (IOException ex) { + baseDirPath = baseDir.toString(); + } + dirty = false; + // + // load any existing dependencies from file + dependenciesFile = new File(baseDir, "dependencies.xml"); + } + public void commit(CCTask task) { + // + // if not dirty, no need to update file + // + if (dirty) { + // + // walk through dependencies to get vector of include paths + // identifiers + // + Vector includePaths = getIncludePaths(); + // + // + // write dependency file + // + try { + FileOutputStream outStream = new FileOutputStream( + dependenciesFile); + OutputStreamWriter streamWriter; + // + // Early VM's may not have UTF-8 support + // fallback to default code page which + // "should" be okay unless there are + // non ASCII file names + String encodingName = "UTF-8"; + try { + streamWriter = new OutputStreamWriter(outStream, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + streamWriter = new OutputStreamWriter(outStream); + encodingName = streamWriter.getEncoding(); + } + BufferedWriter writer = new BufferedWriter(streamWriter); + writer.write("\n"); + writer.write("\n"); + StringBuffer buf = new StringBuffer(); + Enumeration includePathEnum = includePaths.elements(); + while (includePathEnum.hasMoreElements()) { + writeIncludePathDependencies((String) includePathEnum + .nextElement(), writer, buf); + } + writer.write("\n"); + writer.close(); + dirty = false; + } catch (IOException ex) { + task.log("Error writing " + dependenciesFile.toString() + ":" + + ex.toString()); + } + } + } + /** + * Returns an enumerator of DependencyInfo's + */ + public Enumeration elements() { + return dependencies.elements(); + } + /** + * This method returns a DependencyInfo for the specific source file and + * include path identifier + * + */ + public DependencyInfo getDependencyInfo(String sourceRelativeName, + String includePathIdentifier) { + DependencyInfo dependInfo = null; + DependencyInfo[] dependInfos = (DependencyInfo[]) dependencies + .get(sourceRelativeName); + if (dependInfos != null) { + for (int i = 0; i < dependInfos.length; i++) { + dependInfo = dependInfos[i]; + if (dependInfo.getIncludePathIdentifier().equals( + includePathIdentifier)) { + return dependInfo; + } + } + } + return null; + } + private Vector getIncludePaths() { + Vector includePaths = new Vector(); + DependencyInfo[] dependInfos; + Enumeration dependenciesEnum = dependencies.elements(); + while (dependenciesEnum.hasMoreElements()) { + dependInfos = (DependencyInfo[]) dependenciesEnum.nextElement(); + for (int i = 0; i < dependInfos.length; i++) { + DependencyInfo dependInfo = dependInfos[i]; + boolean matchesExisting = false; + final String dependIncludePath = dependInfo + .getIncludePathIdentifier(); + Enumeration includePathEnum = includePaths.elements(); + while (includePathEnum.hasMoreElements()) { + if (dependIncludePath.equals(includePathEnum.nextElement())) { + matchesExisting = true; + break; + } + } + if (!matchesExisting) { + includePaths.addElement(dependIncludePath); + } + } + } + return includePaths; + } + public void load() throws IOException, ParserConfigurationException, + SAXException { + dependencies.clear(); + if (dependenciesFile.exists()) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(false); + SAXParser parser = factory.newSAXParser(); + parser.parse(dependenciesFile, new DependencyTableHandler(this, + baseDir)); + dirty = false; + } + } + /** + * Determines if the specified target needs to be rebuilt. + * + * This task may result in substantial IO as files are parsed to determine + * their dependencies + */ + public boolean needsRebuild(CCTask task, TargetInfo target, + int dependencyDepth) { + // look at any files where the compositeLastModified + // is not known, but the includes are known + // + boolean mustRebuild = false; + CompilerConfiguration compiler = (CompilerConfiguration) target + .getConfiguration(); + String includePathIdentifier = compiler.getIncludePathIdentifier(); + File[] sources = target.getSources(); + DependencyInfo[] dependInfos = new DependencyInfo[sources.length]; + long outputLastModified = target.getOutput().lastModified(); + // + // try to solve problem using existing dependency info + // (not parsing any new files) + // + DependencyInfo[] stack = new DependencyInfo[50]; + boolean rebuildOnStackExhaustion = true; + if (dependencyDepth >= 0) { + if (dependencyDepth < 50) { + stack = new DependencyInfo[dependencyDepth]; + } + rebuildOnStackExhaustion = false; + } + TimestampChecker checker = new TimestampChecker(outputLastModified, + rebuildOnStackExhaustion); + for (int i = 0; i < sources.length && !mustRebuild; i++) { + File source = sources[i]; + String relative = CUtil.getRelativePath(baseDirPath, source); + DependencyInfo dependInfo = getDependencyInfo(relative, + includePathIdentifier); + if (dependInfo == null) { + task.log("Parsing " + relative, Project.MSG_VERBOSE); + dependInfo = parseIncludes(task, compiler, source); + } + walkDependencies(task, dependInfo, compiler, stack, checker); + mustRebuild = checker.getMustRebuild(); + } + return mustRebuild; + } + public DependencyInfo parseIncludes(CCTask task, + CompilerConfiguration compiler, File source) { + DependencyInfo dependInfo = compiler.parseIncludes(task, baseDir, + source); + String relativeSource = CUtil.getRelativePath(baseDirPath, source); + putDependencyInfo(relativeSource, dependInfo); + return dependInfo; + } + private void putDependencyInfo(String key, DependencyInfo dependInfo) { + // + // optimistic, add new value + // + DependencyInfo[] old = (DependencyInfo[]) dependencies.put(key, + new DependencyInfo[]{dependInfo}); + dirty = true; + // + // something was already there + // + if (old != null) { + // + // see if the include path matches a previous entry + // if so replace it + String includePathIdentifier = dependInfo + .getIncludePathIdentifier(); + for (int i = 0; i < old.length; i++) { + DependencyInfo oldDepend = old[i]; + if (oldDepend.getIncludePathIdentifier().equals( + includePathIdentifier)) { + old[i] = dependInfo; + dependencies.put(key, old); + return; + } + } + // + // no match prepend the new entry to the array + // of dependencies for the file + DependencyInfo[] combined = new DependencyInfo[old.length + 1]; + combined[0] = dependInfo; + for (int i = 0; i < old.length; i++) { + combined[i + 1] = old[i]; + } + dependencies.put(key, combined); + } + return; + } + public void walkDependencies(CCTask task, DependencyInfo dependInfo, + CompilerConfiguration compiler, DependencyInfo[] stack, + DependencyVisitor visitor) throws BuildException { + // + // visit this node + // if visit returns true then + // visit the referenced include and sysInclude dependencies + // + if (visitor.visit(dependInfo)) { + // + // find first null entry on stack + // + int stackPosition = -1; + for (int i = 0; i < stack.length; i++) { + if (stack[i] == null) { + stackPosition = i; + stack[i] = dependInfo; + break; + } else { + // + // if we have appeared early in the calling history + // then we didn't exceed the criteria + if (stack[i] == dependInfo) { + return; + } + } + } + if (stackPosition == -1) { + visitor.stackExhausted(); + return; + } + // + // locate dependency infos + // + String[] includes = dependInfo.getIncludes(); + String includePathIdentifier = compiler.getIncludePathIdentifier(); + DependencyInfo[] includeInfos = new DependencyInfo[includes.length]; + for (int i = 0; i < includes.length; i++) { + DependencyInfo includeInfo = getDependencyInfo(includes[i], + includePathIdentifier); + includeInfos[i] = includeInfo; + } + // + // preview with only the already available dependency infos + // + if (visitor.preview(dependInfo, includeInfos)) { + // + // now need to fill in the missing DependencyInfos + // + int missingCount = 0; + for (int i = 0; i < includes.length; i++) { + if (includeInfos[i] == null) { + missingCount++; + task.log("Parsing " + includes[i], Project.MSG_VERBOSE); + // + // If the include filepath is relative + // then anchor it the base directory + File src = new File(includes[i]); + if (!src.isAbsolute()) { + src = new File(baseDir, includes[i]); + } + DependencyInfo includeInfo = parseIncludes(task, + compiler, src); + includeInfos[i] = includeInfo; + } + } + // + // if it passes a review the second time + // then recurse into all the children + if (missingCount == 0 + || visitor.preview(dependInfo, includeInfos)) { + // + // recurse into + // + for (int i = 0; i < includeInfos.length; i++) { + DependencyInfo includeInfo = includeInfos[i]; + walkDependencies(task, includeInfo, compiler, stack, + visitor); + } + } + } + stack[stackPosition] = null; + } + } + private void writeDependencyInfo(BufferedWriter writer, StringBuffer buf, + DependencyInfo dependInfo) throws IOException { + String[] includes = dependInfo.getIncludes(); + String[] sysIncludes = dependInfo.getSysIncludes(); + // + // if the includes have not been evaluted then + // it is not worth our time saving it + // and trying to distiguish between files with + // no dependencies and those with undetermined dependencies + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + for (int i = 0; i < includes.length; i++) { + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + } + for (int i = 0; i < sysIncludes.length; i++) { + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + } + writer.write(" \n"); + return; + } + private void writeIncludePathDependencies(String includePathIdentifier, + BufferedWriter writer, StringBuffer buf) throws IOException { + // + // include path element + // + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + Enumeration dependenciesEnum = dependencies.elements(); + while (dependenciesEnum.hasMoreElements()) { + DependencyInfo[] dependInfos = (DependencyInfo[]) dependenciesEnum + .nextElement(); + for (int i = 0; i < dependInfos.length; i++) { + DependencyInfo dependInfo = dependInfos[i]; + // + // if this is for the same include path + // then output the info + if (dependInfo.getIncludePathIdentifier().equals( + includePathIdentifier)) { + writeDependencyInfo(writer, buf, dependInfo); + } + } + } + writer.write(" \n"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java b/src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java new file mode 100644 index 0000000..f40ac8e --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/DistributerDef.java @@ -0,0 +1,243 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + + +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; +import java.util.Vector; + +/** + * Distributed build information (Non-functional prototype). + * + */ +public final class DistributerDef + extends DataType { + /** + * if property. + */ + private String ifCond; + + /** + * unless property. + */ + private String unlessCond; + + /** + * hosts. + * + */ + private String hosts; + + /** + * Protocol. + * + */ + private DistributerProtocolEnum protocol; + + /** + * Not sure what this is. + */ + private int tcpCork; + + /** + * user name. + */ + private String user; + + /** + * local to remote file name maps. + */ + private final Vector maps = new Vector(); + + /** + * Constructor. + * + */ + public DistributerDef() { + } + + /** + * Required by documentation generator. + */ + public void execute() { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + + /** + * Returns true if the if and unless conditions (if any) are + * satisfied. + * @return true if definition is active. + */ + public boolean isActive() { + return CUtil.isActive(getProject(), ifCond, unlessCond); + } + + /** + * Sets an id that can be used to reference this element. + * + * @param id + * id + */ + public void setId(final String id) { + // + // this is actually accomplished by a different + // mechanism, but we can document it + // + } + + /** + * Sets the property name for the 'if' condition. + * + * The define will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public void setIf(final String propName) { + ifCond = propName; + } + + /** + * Specifies that this element should behave as if the content of the + * element with the matching id attribute was inserted at this location. If + * specified, no other attributes should be specified. + * @param r reference name + */ + public void setRefid(final Reference r) { + super.setRefid(r); + } + + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the define will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(final String propName) { + unlessCond = propName; + } + + /** + * Gets hosts. + * @return hosts, may be null. + * + */ + public String getHosts() { + if (isReference()) { + DistributerDef refDistributer = (DistributerDef) + getCheckedRef(DistributerDef.class, + "DistributerDef"); + return refDistributer.getHosts(); + } + return hosts; + } + + /** + * Gets tcp cork. + * @return TCP_CORK value. + * + */ + public int getTcpcork() { + if (isReference()) { + DistributerDef refDistributer = (DistributerDef) + getCheckedRef(DistributerDef.class, + "DistributerDef"); + return refDistributer.getTcpcork(); + } + return tcpCork; + } + + /** + * Gets protocol. + * @return protocol, may be null. + * + */ + public DistributerProtocolEnum getProtocol() { + if (isReference()) { + DistributerDef refDistributer = (DistributerDef) + getCheckedRef(DistributerDef.class, + "DistributerDef"); + return refDistributer.getProtocol(); + } + return protocol; + } + + /** + * Sets hosts. + * @param value new value + */ + public void setHosts(final String value) { + if (isReference()) { + throw tooManyAttributes(); + } + hosts = value; + } + + /** + * Sets TCP_CORK value. + * @param value new value + */ + public void setTcpcork(final int value) { + if (isReference()) { + throw tooManyAttributes(); + } + tcpCork = value; + } + + /** + * Sets protocol. + * @param value new value + */ + public void setProtocol(final DistributerProtocolEnum value) { + if (isReference()) { + throw tooManyAttributes(); + } + protocol = value; + } + + /** + * Local to remote filename maps. + * @return new map + */ + public DistributerMap createMap() { + DistributerMap map = new DistributerMap(); + map.setProject(getProject()); + maps.addElement(map); + return map; + } + + /** + * Sets remote user name. + * @param value user name + */ + public void setUser(final String value) { + user = value; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java b/src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java new file mode 100644 index 0000000..ec0f4a4 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/DistributerMap.java @@ -0,0 +1,218 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.io.File; +import java.io.IOException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.DataType; + +/** + * Local to remote filename mapping (Experimental). + * + */ +public final class DistributerMap + extends DataType { + /** + * if property. + */ + private String ifCond; + + /** + * unless property. + */ + private String unlessCond; + + /** + * local directory name. + * + */ + private File localName; + + /** + * Canonical local file name. + */ + private String canonicalPath; + + /** + * remote name. + * + */ + private String remoteName; + + /** + * Separator (/ or \) character on remote system. + */ + private char remoteSeparator = File.separatorChar; + + /** + * hosts that for which this map is valid. + * + */ + private String hosts; + + /** + * Constructor. + * + */ + public DistributerMap() { + } + + /** + * Required by documentation generator. + */ + public void execute() { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + + /** + * Returns true if the if and unless conditions (if any) are + * satisfied. + * + * @return true if this object is active. + */ + public boolean isActive() { + return CUtil.isActive(getProject(), ifCond, unlessCond); + } + + /** + * Sets the property name for the 'if' condition. + * + * This object will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public void setIf(final String propName) { + ifCond = propName; + } + + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the define will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(final String propName) { + unlessCond = propName; + } + + /** + * Gets local directory. + * @return local directory, may be null. + * + */ + public File getLocal() { + return localName; + } + + /** + * Gets remote name for directory. + * @return remote name, may be null. + * + */ + public String getRemote() { + return remoteName; + } + + /** + * Converts the local file name to the remote name for the same file. + * + * @param host host + * @param localFile local file + * @return remote name for local file, null if unknown. + */ + public String toRemote(final String host, final File localFile) { + if (remoteName != null + && (hosts == null || hosts.indexOf(host) >= 0)) { + try { + String canonical = localFile.getCanonicalPath(); + if (canonical.startsWith(canonicalPath)) { + if (isActive()) { + return remoteName + + canonical.substring(canonicalPath.length()).replace(File. + separatorChar, remoteSeparator); + } + } + } catch (IOException ex) { + return null; + } + } + return null; + } + + /** + * Sets local directory for base of mapping. + * + * @param value value + */ + public void setLocal(final File value) { + if (value == null) { + throw new NullPointerException("value"); + } + if (value.exists() && !value.isDirectory()) { + throw new BuildException("local should be a directory"); + } + localName = value; + try { + canonicalPath = localName.getCanonicalPath(); + } catch (IOException ex) { + throw new BuildException(ex); + } + } + + /** + * Sets remote name for directory. + * @param value remote name for directory + */ + public void setRemote(final String value) { + remoteName = value; + } + + /** + * Sets the separator character (/ or \) for the remote system. + * @param value separator character + */ + public void setRemoteSeparator(final String value) { + if (value != null && value.length() != 1) { + throw new BuildException("remote separator must be a single character"); + } + remoteSeparator = value.charAt(0); + } + + /** + * Sets hosts for which this mapping is valid. + * + * @param value hosts + */ + public void setHosts(final String value) { + hosts = value; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java new file mode 100644 index 0000000..7d3734d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java @@ -0,0 +1,50 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Distributer prococol names (experimental). + * + * @author Curt Arnold + * + */ +public final class DistributerProtocolEnum + extends EnumeratedAttribute { + /** + * Constructor. + * + * Set by default to "distcc" + * + * @see java.lang.Object#Object() + */ + public DistributerProtocolEnum() { + setValue("distcc"); + } + + /** + * Gets list of acceptable values. + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] { + "distcc", + "ssh"}; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java b/src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java new file mode 100644 index 0000000..c59f04f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/FileVisitor.java @@ -0,0 +1,27 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; + +import org.apache.tools.ant.BuildException; +/** + * An abstract class implemented to walk over the fileset members of a + * ProcessorDef + */ +public interface FileVisitor { + abstract void visit(File parentDir, String filename) throws BuildException; +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java b/src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java new file mode 100644 index 0000000..cde8837 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/LinkerDef.java @@ -0,0 +1,509 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.util.Enumeration; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.gcc.GccLinker; +import net.sf.antcontrib.cpptasks.types.FlexLong; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LinkerArgument; +import net.sf.antcontrib.cpptasks.types.SystemLibrarySet; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.FlexInteger; +/** + * A linker definition. linker elements may be placed either as children of a + * cc element or the project element. A linker element with an id attribute may + * be referenced by linker elements with refid or extends attributes. + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public class LinkerDef extends ProcessorDef { + private long base; + private String entry; + private Boolean fixed; + private Boolean incremental; + private final Vector librarySets = new Vector(); + private Boolean map; + private int stack; + private final Vector sysLibrarySets = new Vector(); + /** + * Default constructor + * + * @see java.lang.Object#Object() + */ + public LinkerDef() { + base = -1; + stack = -1; + } + private void addActiveLibrarySet(Project project, Vector libsets, + Vector srcSets) { + Enumeration srcenum = srcSets.elements(); + while (srcenum.hasMoreElements()) { + LibrarySet set = (LibrarySet) srcenum.nextElement(); + if (set.isActive(project)) { + libsets.addElement(set); + } + } + } + private void addActiveSystemLibrarySets(Project project, Vector libsets) { + addActiveLibrarySet(project, libsets, sysLibrarySets); + } + private void addActiveUserLibrarySets(Project project, Vector libsets) { + addActiveLibrarySet(project, libsets, librarySets); + } + /** + * Adds a linker command-line arg. + */ + public void addConfiguredLinkerArg(LinkerArgument arg) { + addConfiguredProcessorArg(arg); + } + /** + * Adds a compiler command-line arg. + */ + public void addConfiguredLinkerParam(LinkerParam param) { + if (isReference()) { + throw noChildrenAllowed(); + } + addConfiguredProcessorParam(param); + } + /** + * Adds a system library set. + */ + public void addLibset(LibrarySet libset) { + if (isReference()) { + throw super.noChildrenAllowed(); + } + if (libset == null) { + throw new NullPointerException("libset"); + } + librarySets.addElement(libset); + } + /** + * Adds a system library set. + */ + public void addSyslibset(SystemLibrarySet libset) { + if (isReference()) { + throw super.noChildrenAllowed(); + } + if (libset == null) { + throw new NullPointerException("libset"); + } + sysLibrarySets.addElement(libset); + } + + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** + * Returns an array of active library sets for this linker definition. + */ + public LibrarySet[] getActiveLibrarySets(LinkerDef[] defaultProviders, + int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getActiveUserLibrarySets(defaultProviders, index); + } + Project p = getProject(); + Vector libsets = new Vector(); + for (int i = index; i < defaultProviders.length; i++) { + defaultProviders[i].addActiveUserLibrarySets(p, libsets); + } + addActiveUserLibrarySets(p, libsets); + for (int i = index; i < defaultProviders.length; i++) { + defaultProviders[i].addActiveSystemLibrarySets(p, libsets); + } + addActiveSystemLibrarySets(p, libsets); + LibrarySet[] sets = new LibrarySet[libsets.size()]; + libsets.copyInto(sets); + return sets; + } + /** + * Returns an array of active library sets for this linker definition. + */ + public LibrarySet[] getActiveSystemLibrarySets( + LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getActiveUserLibrarySets(defaultProviders, index); + } + Project p = getProject(); + Vector libsets = new Vector(); + for (int i = index; i < defaultProviders.length; i++) { + defaultProviders[i].addActiveSystemLibrarySets(p, libsets); + } + addActiveSystemLibrarySets(p, libsets); + LibrarySet[] sets = new LibrarySet[libsets.size()]; + libsets.copyInto(sets); + return sets; + } + /** + * Returns an array of active library sets for this linker definition. + */ + public LibrarySet[] getActiveUserLibrarySets(LinkerDef[] defaultProviders, + int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getActiveUserLibrarySets(defaultProviders, index); + } + Project p = getProject(); + Vector libsets = new Vector(); + for (int i = index; i < defaultProviders.length; i++) { + defaultProviders[i].addActiveUserLibrarySets(p, libsets); + } + addActiveUserLibrarySets(p, libsets); + LibrarySet[] sets = new LibrarySet[libsets.size()]; + libsets.copyInto(sets); + return sets; + } + public long getBase(LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getBase(defaultProviders, index); + } + if (base <= 0) { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getBase(defaultProviders, + index + 1); + } + } + return base; + } + public Boolean getFixed(LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getFixed(defaultProviders, index); + } + if (fixed == null) { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getFixed(defaultProviders, + index + 1); + } + } + return fixed; + } + public boolean getIncremental(LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getIncremental(defaultProviders, index); + } + if (incremental != null) { + return incremental.booleanValue(); + } + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getIncremental(defaultProviders, index + 1); + } + return false; + } + public boolean getMap(LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getMap(defaultProviders, index); + } + if (map != null) { + return map.booleanValue(); + } + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getMap(defaultProviders, index + 1); + } + return false; + } + public String getEntry(LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getEntry(defaultProviders, index); + } + if (entry != null) { + return entry; + } + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getEntry(defaultProviders, index + 1); + } + return null; + } + + public Processor getProcessor() { + Linker linker = (Linker) super.getProcessor(); + if (linker == null) { + linker = GccLinker.getInstance(); + } + if (getLibtool() && linker instanceof CommandLineLinker) { + CommandLineLinker cmdLineLinker = (CommandLineLinker) linker; + linker = cmdLineLinker.getLibtoolLinker(); + } + return linker; + } + + public Processor getProcessor(LinkType linkType) { + Processor proc = getProcessor(); + return proc.getLinker(linkType); + } + + public int getStack(LinkerDef[] defaultProviders, int index) { + if (isReference()) { + return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef")) + .getStack(defaultProviders, index); + } + if (stack < 0) { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getStack(defaultProviders, + index + 1); + } + } + return stack; + } + /** + * Sets the base address. May be specified in either decimal or hex. + * + * @param base + * base address + * + */ + public void setBase(FlexLong base) { + if (isReference()) { + throw tooManyAttributes(); + } + this.base = base.longValue(); + } + /** + * Sets the starting address. + * + * @param entry + * function name + */ + public void setEntry(String entry) { + if (isReference()) { + throw tooManyAttributes(); + } + this.entry = entry; + } + /** + * If true, marks the file to be loaded only at its preferred address. + */ + public void setFixed(boolean fixed) { + if (isReference()) { + throw tooManyAttributes(); + } + this.fixed = booleanValueOf(fixed); + } + /** + * If true, allows incremental linking. + * + */ + public void setIncremental(boolean incremental) { + if (isReference()) { + throw tooManyAttributes(); + } + this.incremental = booleanValueOf(incremental); + } + /** + * If set to true, a map file will be produced. + */ + public void setMap(boolean map) { + if (isReference()) { + throw tooManyAttributes(); + } + this.map = booleanValueOf(map); + } + /** + * Sets linker type. + * + * + * Supported linkers + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
gccGcc Linker
g++G++ Linker
ldLd Linker
arGcc Librarian
msvcMicrosoft Linker
bccBorland Linker
dfCompaq Visual Fortran Linker
iclIntel Linker for Windows (IA-32)
eclIntel Linker for Windows (IA-64)
iccIntel Linker for Linux (IA-32)
eccIntel Linker for Linux (IA-64)
CCSun ONE Linker
aCCHP aC++ Linker
os390OS390 Linker
os390batchOS390 Linker
os400IccLinker
sunc89C89 Linker
xlCVisualAge Linker
wclOpenWatcom C/C++ linker
wflOpenWatcom FORTRAN linker
+ * + */ + public void setName(LinkerEnum name) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + Linker linker = name.getLinker(); + super.setProcessor(linker); + } + protected void setProcessor(Processor proc) throws BuildException { + Linker linker = null; + if (proc instanceof Linker) { + linker = (Linker) proc; + } else { + LinkType linkType = new LinkType(); + linker = proc.getLinker(linkType); + } + super.setProcessor(linker); + } + /** + * Sets stack size in bytes. + */ + public void setStack(FlexInteger stack) { + if (isReference()) { + throw tooManyAttributes(); + } + this.stack = stack.intValue(); + } + public void visitSystemLibraries(Linker linker, FileVisitor libraryVisitor) { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project must be set"); + } + if (isReference()) { + LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class, + "Linker")); + master.visitSystemLibraries(linker, libraryVisitor); + } else { + // + // if this linker extends another, + // visit its libraries first + // + LinkerDef extendsDef = (LinkerDef) getExtends(); + if (extendsDef != null) { + extendsDef.visitSystemLibraries(linker, libraryVisitor); + } + if (sysLibrarySets.size() > 0) { + File[] libpath = linker.getLibraryPath(); + for (int i = 0; i < sysLibrarySets.size(); i++) { + LibrarySet set = (LibrarySet) sysLibrarySets.elementAt(i); + if (set.isActive(p)) { + set.visitLibraries(p, linker, libpath, + libraryVisitor); + } + } + } + } + } + public void visitUserLibraries(Linker linker, FileVisitor libraryVisitor) { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project must be set"); + } + if (isReference()) { + LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class, + "Linker")); + master.visitUserLibraries(linker, libraryVisitor); + } else { + // + // if this linker extends another, + // visit its libraries first + // + LinkerDef extendsDef = (LinkerDef) getExtends(); + if (extendsDef != null) { + extendsDef.visitUserLibraries(linker, libraryVisitor); + } + // + // visit the user libraries + // + if (librarySets.size() > 0) { + File[] libpath = linker.getLibraryPath(); + for (int i = 0; i < librarySets.size(); i++) { + LibrarySet set = (LibrarySet) librarySets.elementAt(i); + if (set.isActive(p)) { + set.visitLibraries(p, linker, libpath, + libraryVisitor); + } + } + } + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java new file mode 100644 index 0000000..df96723 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/LinkerEnum.java @@ -0,0 +1,112 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import net.sf.antcontrib.cpptasks.arm.ADSLinker; +import net.sf.antcontrib.cpptasks.borland.BorlandLinker; +import net.sf.antcontrib.cpptasks.compaq.CompaqVisualFortranLinker; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker; +import net.sf.antcontrib.cpptasks.gcc.GccLibrarian; +import net.sf.antcontrib.cpptasks.gcc.GccLinker; +import net.sf.antcontrib.cpptasks.gcc.GppLinker; +import net.sf.antcontrib.cpptasks.gcc.LdLinker; +import net.sf.antcontrib.cpptasks.hp.aCCLinker; +import net.sf.antcontrib.cpptasks.ibm.VisualAgeLinker; +import net.sf.antcontrib.cpptasks.intel.IntelLinux32Linker; +import net.sf.antcontrib.cpptasks.intel.IntelLinux64Linker; +import net.sf.antcontrib.cpptasks.intel.IntelWin32Linker; +import net.sf.antcontrib.cpptasks.os390.OS390Linker; +import net.sf.antcontrib.cpptasks.os400.IccLinker; +import net.sf.antcontrib.cpptasks.sun.C89Linker; +import net.sf.antcontrib.cpptasks.sun.ForteCCLinker; +import net.sf.antcontrib.cpptasks.ti.ClxxLinker; +import org.apache.tools.ant.types.EnumeratedAttribute; +import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomCLinker; +import net.sf.antcontrib.cpptasks.openwatcom.OpenWatcomFortranLinker; + +/** + * Enumeration of supported linkers + * + * @author Curt Arnold + * + */ +public class LinkerEnum extends EnumeratedAttribute { + private final static ProcessorEnumValue[] linkers = new ProcessorEnumValue[]{ + new ProcessorEnumValue("gcc", GccLinker.getInstance()), + new ProcessorEnumValue("g++", GppLinker.getInstance()), + new ProcessorEnumValue("ld", LdLinker.getInstance()), + new ProcessorEnumValue("ar", GccLibrarian.getInstance()), + new ProcessorEnumValue("msvc", DevStudioLinker.getInstance()), + new ProcessorEnumValue("bcc", BorlandLinker.getInstance()), + new ProcessorEnumValue("df", CompaqVisualFortranLinker + .getInstance()), + new ProcessorEnumValue("icl", IntelWin32Linker.getInstance()), + new ProcessorEnumValue("ecl", IntelWin32Linker.getInstance()), + new ProcessorEnumValue("icc", IntelLinux32Linker.getInstance()), + new ProcessorEnumValue("ecc", IntelLinux64Linker.getInstance()), + new ProcessorEnumValue("CC", ForteCCLinker.getInstance()), + new ProcessorEnumValue("aCC", aCCLinker.getInstance()), + new ProcessorEnumValue("os390", OS390Linker.getInstance()), + new ProcessorEnumValue("os390batch", OS390Linker + .getDataSetInstance()), + new ProcessorEnumValue("os400", IccLinker.getInstance()), + new ProcessorEnumValue("sunc89", C89Linker.getInstance()), + new ProcessorEnumValue("xlC", VisualAgeLinker.getInstance()), + new ProcessorEnumValue("cl6x", ClxxLinker.getCl6xInstance()), + new ProcessorEnumValue("cl55", ClxxLinker.getCl55Instance()), + new ProcessorEnumValue("armcc", ADSLinker.getInstance()), + new ProcessorEnumValue("armcpp", ADSLinker.getInstance()), + new ProcessorEnumValue("tcc", ADSLinker.getInstance()), + new ProcessorEnumValue("tcpp", ADSLinker.getInstance()), + // gcc cross compilers + new ProcessorEnumValue( + "sparc-sun-solaris2-gcc", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccLinker + .getInstance()), + new ProcessorEnumValue( + "sparc-sun-solaris2-g++", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GppLinker + .getInstance()), + new ProcessorEnumValue( + "sparc-sun-solaris2-ld", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.LdLinker + .getInstance()), + new ProcessorEnumValue( + "sparc-sun-solaris2-ar", + net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccLibrarian + .getInstance()), + new ProcessorEnumValue("gcc-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GccLinker + .getInstance()), + new ProcessorEnumValue("g++-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GppLinker + .getInstance()), + new ProcessorEnumValue("ld-cross", + net.sf.antcontrib.cpptasks.gcc.cross.LdLinker.getInstance()), + new ProcessorEnumValue("ar-cross", + net.sf.antcontrib.cpptasks.gcc.cross.GccLibrarian + .getInstance()), + new ProcessorEnumValue("wcl", OpenWatcomCLinker.getInstance()), + new ProcessorEnumValue("wfl", OpenWatcomFortranLinker.getInstance()), + }; + public Linker getLinker() { + return (Linker) linkers[getIndex()].getProcessor(); + } + public String[] getValues() { + return ProcessorEnumValue.getValues(linkers); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java b/src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java new file mode 100644 index 0000000..3dae933 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/LinkerParam.java @@ -0,0 +1,33 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +/******************************************************************************* + * Place class description here. + * + * @author inger + * @author + * + * @since + ******************************************************************************/ +public class LinkerParam extends ProcessorParam { + public LinkerParam() { + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java new file mode 100644 index 0000000..68ebd82 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/OSFamilyEnum.java @@ -0,0 +1,59 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Enumeration of cpu types. + * + * @author Curt Arnold + * + */ +public final class OSFamilyEnum + extends EnumeratedAttribute { + /** + * Constructor. + * + * Set by default to "pentium3" + * + * @see java.lang.Object#Object() + */ + public OSFamilyEnum() { + setValue("windows"); + } + + /** + * Gets list of acceptable values. + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] { + "windows", + "dos", + "mac", + "unix", + "netware", + "os/2", + "tandem", + "win9x", + "z/os", + "os/400", + "openvms"}; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java b/src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java new file mode 100644 index 0000000..fd4cda5 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ObjectFileCollector.java @@ -0,0 +1,42 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.Linker; + +import org.apache.tools.ant.BuildException; +/** + * Collects object files for the link step. + * + * + */ +public final class ObjectFileCollector implements FileVisitor { + private final Vector files; + private final Linker linker; + public ObjectFileCollector(Linker linker, Vector files) { + this.linker = linker; + this.files = files; + } + public void visit(File parentDir, String filename) throws BuildException { + int bid = linker.bid(filename); + if (bid >= 1) { + files.addElement(new File(parentDir, filename)); + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java new file mode 100644 index 0000000..042822e --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/OptimizationEnum.java @@ -0,0 +1,82 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Enumeration of optimization levels (experimental). + * + * @author Curt Arnold + * + */ +public final class OptimizationEnum + extends EnumeratedAttribute { + /** + * Constructor. + * + * Set by default to "speed" + * + * @see java.lang.Object#Object() + */ + public OptimizationEnum() { + setValue("speed"); + } + + /** + * Gets list of acceptable values. + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] { + "none", + "size", + "minimal", + "speed", + "full", + "aggressive", + "extreme", + "unsafe" + }; + } + + /** + * Is size optimized. + * @return boolean true if size is optimized. + */ + public boolean isSize() { + return "size".equals(getValue()); + } + + /** + * Is speed optimized. + * @return boolean true if speed is optimized. + */ + public boolean isSpeed() { + return !isSize() && !isNoOptimization(); + } + + /** + * Is no optimization performed. + * @return boolean true if no optimization is performed. + */ + public boolean isNoOptimization() { + return "none".equals(getValue()); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java new file mode 100644 index 0000000..873a99c --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/OutputTypeEnum.java @@ -0,0 +1,48 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import org.apache.tools.ant.types.EnumeratedAttribute; +/** + * Enumeration of supported subsystems + * + * @author Curt Arnold + * + */ +public class OutputTypeEnum extends EnumeratedAttribute { + /** + * Constructor + * + * Set by default to "executable" + * + * @see java.lang.Object#Object() + */ + public OutputTypeEnum() { + setValue("executable"); + } + /** + * Gets list of acceptable values + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[]{"executable", // executable program + "plugin", // plugin module + "shared", // dynamically linkable module + "static" // convenience library + }; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java new file mode 100644 index 0000000..b642197 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileDef.java @@ -0,0 +1,212 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.util.Enumeration; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.types.DataType; +/** + * An element that specifies a prototype file and rules for source files that + * should not use precompiled headers + * + * @author Curt Arnold + */ +public final class PrecompileDef extends DataType { + private final Vector exceptSets = new Vector(); + private String ifCond; + /** + * Directory of prototype file + */ + private File prototype = new File("stdafx.cpp"); + private String unlessCond; + /** + * Constructor + * + */ + public PrecompileDef() { + } + /** + * Method used by PrecompileExceptDef to add exception set to + * PrecompileDef. + */ + public void appendExceptFileSet(ConditionalFileSet exceptSet) { + exceptSet.setProject(getProject()); + exceptSets.addElement(exceptSet); + } + /** + * Adds filesets that specify files that should not be processed with + * precompiled headers enabled. + * + */ + public PrecompileExceptDef createExcept() { + return new PrecompileExceptDef(this); + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + public String[] getExceptFiles() { + PrecompileDef ref = getRef(); + if (ref != null) { + return ref.getExceptFiles(); + } + if (exceptSets.size() == 0) { + return new String[0]; + } + Project p = getProject(); + String[] exceptFiles = null; + Enumeration setEnum = exceptSets.elements(); + while (setEnum.hasMoreElements()) { + ConditionalFileSet exceptSet = (ConditionalFileSet) setEnum + .nextElement(); + if (exceptSet.isActive()) { + DirectoryScanner scanner = exceptSet + .getDirectoryScanner(p); + String[] scannerFiles = scanner.getIncludedFiles(); + if (exceptFiles == null) { + exceptFiles = scannerFiles; + } else { + if (scannerFiles.length > 0) { + String[] newFiles = new String[exceptFiles.length + + scannerFiles.length]; + for (int i = 0; i < exceptFiles.length; i++) { + newFiles[i] = exceptFiles[i]; + } + int index = exceptFiles.length; + for (int i = 0; i < scannerFiles.length; i++) { + newFiles[index++] = scannerFiles[i]; + } + exceptFiles = newFiles; + } + } + } + } + if (exceptFiles == null) { + exceptFiles = new String[0]; + } + return exceptFiles; + } + /** + * Gets prototype source file + * + */ + public File getPrototype() { + PrecompileDef ref = getRef(); + if (ref != null) { + return ref.getPrototype(); + } + return prototype; + } + private PrecompileDef getRef() { + if (isReference()) { + return ((PrecompileDef) getCheckedRef(PrecompileDef.class, + "PrecompileDef")); + } + return null; + } + public boolean isActive() { + boolean isActive = CUtil.isActive(getProject(), ifCond, unlessCond); + if (!isActive) { + PrecompileDef ref = getRef(); + if (ref != null) { + return ref.isActive(); + } + } + return isActive; + } + /** + * Sets a description of the current data type. + */ + public void setDescription(String desc) { + super.setDescription(desc); + } + /** + * Sets an id that can be used to reference this element. + * + * @param id + * id + */ + public void setId(String id) { + // + // this is actually accomplished by a different + // mechanism, but we can document it + // + } + /** + * Set the 'if' condition. + * + * The processor will be ignored unless the property is defined. + * + * The value of property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * isActive() is evaluated. + * + * @param propName + * name of property + */ + public void setIf(String propName) { + ifCond = propName; + } + /** + * Sets file to precompile. + * + * Should be a source file that includes only one unguarded header file. + * Default value is "stdafx.cpp". + * + * @param prototype + * file path for prototype source file + */ + public void setPrototype(File prototype) { + if (isReference()) { + throw tooManyAttributes(); + } + if (prototype == null) { + throw new NullPointerException("prototype"); + } + this.prototype = prototype; + } + /** + * Specifies that this element should behave as if the content of the + * element with the matching id attribute was inserted at this location. + * + * @param ref + * Reference to other element + * + */ + public void setRefid(org.apache.tools.ant.types.Reference ref) { + super.setRefid(ref); + } + /** + * Set the 'unless' condition. If named property exists at execution time, + * the processor will be ignored. + * + * Value of property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when isActive is called. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessCond = propName; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java new file mode 100644 index 0000000..c6c7da7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java @@ -0,0 +1,80 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; + +import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; + +import org.apache.tools.ant.BuildException; +/** + * Specifies files that should not be compiled using precompiled headers. + * + * @author Curt Arnold + */ +public final class PrecompileExceptDef { + private ConditionalFileSet localSet = null; + /** + * Collection of contained by definition + */ + private PrecompileDef owner; + /** + * Constructor + * + */ + public PrecompileExceptDef(PrecompileDef owner) { + this.owner = owner; + } + /** + * Adds filesets that specify files that should not be processed using + * precompiled headers. + * + * @param exceptSet + * FileSet specify files that should not be processed with + * precompiled headers enabled. + */ + public void addFileset(ConditionalFileSet exceptSet) { + owner.appendExceptFileSet(exceptSet); + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** + * Sets the base-directory + */ + public void setDir(File dir) throws BuildException { + if (localSet == null) { + localSet = new ConditionalFileSet(); + owner.appendExceptFileSet(localSet); + } + localSet.setDir(dir); + } + /** + * Comma or space separated list of file patterns that should not be + * compiled using precompiled headers. + * + * @param includes + * the string containing the include patterns + */ + public void setIncludes(String includes) { + if (localSet == null) { + localSet = new ConditionalFileSet(); + owner.appendExceptFileSet(localSet); + } + localSet.setIncludes(includes); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java new file mode 100644 index 0000000..54a3406 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java @@ -0,0 +1,679 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.lang.reflect.Method; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.types.CommandLineArgument; +import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Environment; +import org.apache.tools.ant.types.Reference; +/** + * An abstract compiler/linker definition. + * + * @author Curt Arnold + */ +public abstract class ProcessorDef extends DataType { + /** + * Returns the equivalent Boolean object for the specified value + * + * Equivalent to Boolean.valueOf in JDK 1.4 + * + * @param val + * boolean value + * @return Boolean.TRUE or Boolean.FALSE + */ + protected static Boolean booleanValueOf(boolean val) { + if (val) { + return Boolean.TRUE; + } + return Boolean.FALSE; + } + /** + * if true, targets will be built for debugging + */ + private Boolean debug; + private Environment env = null; + /** + * Reference for "extends" processor definition + */ + private Reference extendsRef = null; + /** + * Name of property that must be present or definition will be ignored. May + * be null. + */ + private String ifProp; + /** + * if true, processor definition inherits values from containing cc + * element + */ + private boolean inherit; + private Boolean libtool = null; + protected boolean newEnvironment = false; + /** + * Processor. + */ + private Processor processor; + /** + * Collection of or contained by definition + */ + private final Vector processorArgs = new Vector(); + /** + * Collection of or contained by definition + */ + private final Vector processorParams = new Vector(); + /** + * if true, all targets will be unconditionally rebuilt + */ + private Boolean rebuild; + /** + * Collection of contained by definition + */ + private final Vector srcSets = new Vector(); + /** + * Name of property that if present will cause definition to be ignored. + * May be null. + */ + private String unlessProp; + /** + * Constructor + * + */ + protected ProcessorDef() throws NullPointerException { + inherit = true; + } + /** + * Adds a or + * + * @param arg + * command line argument, must not be null + * @throws NullPointerException + * if arg is null + * @throws BuildException + * if this definition is a reference + */ + protected void addConfiguredProcessorArg(CommandLineArgument arg) + throws NullPointerException, BuildException { + if (arg == null) { + throw new NullPointerException("arg"); + } + if (isReference()) { + throw noChildrenAllowed(); + } + processorArgs.addElement(arg); + } + /** + * Adds a or + * + * @param param + * command line argument, must not be null + * @throws NullPointerException + * if arg is null + * @throws BuildException + * if this definition is a reference + */ + protected void addConfiguredProcessorParam(ProcessorParam param) + throws NullPointerException, BuildException { + if (param == null) { + throw new NullPointerException("param"); + } + if (isReference()) { + throw noChildrenAllowed(); + } + processorParams.addElement(param); + } + /** + * Add an environment variable to the launched process. + */ + public void addEnv(Environment.Variable var) { + if (env == null) { + env = new Environment(); + } + env.addVariable(var); + } + /** + * Adds a source file set. + * + * Files in these set will be processed by this configuration and will not + * participate in the auction. + * + * @param srcSet + * Fileset identifying files that should be processed by this + * processor + * @throws BuildException + * if processor definition is a reference + */ + public void addFileset(ConditionalFileSet srcSet) throws BuildException { + if (isReference()) { + throw noChildrenAllowed(); + } + srcSet.setProject(getProject()); + srcSets.addElement(srcSet); + } + /** + * Creates a configuration + * + * @param baseDef + * reference to def from containing cc element, may be null + * @return configuration + * + */ + public ProcessorConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef baseDef, + TargetDef targetPlatform, VersionInfo versionInfo) { + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).createConfiguration(task, linkType, + baseDef, targetPlatform, versionInfo); + } + ProcessorDef[] defaultProviders = getDefaultProviders(baseDef); + Processor proc = getProcessor(linkType); + return proc.createConfiguration(task, linkType, defaultProviders, this, targetPlatform, versionInfo); + } + /** + * Prepares list of processor arguments ( compilerarg, linkerarg ) that + * are active for the current project settings. + * + * @return active compiler arguments + */ + public CommandLineArgument[] getActiveProcessorArgs() { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project must be set"); + } + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).getActiveProcessorArgs(); + } + Vector activeArgs = new Vector(processorArgs.size()); + for (int i = 0; i < processorArgs.size(); i++) { + CommandLineArgument arg = (CommandLineArgument) processorArgs + .elementAt(i); + if (arg.isActive(p)) { + activeArgs.addElement(arg); + } + } + CommandLineArgument[] array = new CommandLineArgument[activeArgs.size()]; + activeArgs.copyInto(array); + return array; + } + /** + * Prepares list of processor arguments ( compilerarg, linkerarg) that + * are active for the current project settings. + * + * @return active compiler arguments + */ + public ProcessorParam[] getActiveProcessorParams() { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException("project must be set"); + } + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).getActiveProcessorParams(); + } + Vector activeParams = new Vector(processorParams.size()); + for (int i = 0; i < processorParams.size(); i++) { + ProcessorParam param = (ProcessorParam) processorParams + .elementAt(i); + if (param.isActive(p)) { + activeParams.addElement(param); + } + } + ProcessorParam[] array = new ProcessorParam[activeParams.size()]; + activeParams.copyInto(array); + return array; + } + /** + * Gets boolean indicating debug build + * + * @param defaultProviders + * array of ProcessorDef's in descending priority + * @param index + * index to first element in array that should be considered + * @return if true, built targets for debugging + */ + public boolean getDebug(ProcessorDef[] defaultProviders, int index) { + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).getDebug(defaultProviders, index); + } + if (debug != null) { + return debug.booleanValue(); + } else { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getDebug(defaultProviders, + index + 1); + } + } + return false; + } + /** + * Creates an chain of objects which provide default values in descending + * order of significance. + * + * @param baseDef + * corresponding ProcessorDef from CCTask, will be last element + * in array unless inherit = false + * @return default provider array + * + */ + protected final ProcessorDef[] getDefaultProviders(ProcessorDef baseDef) { + ProcessorDef extendsDef = getExtends(); + Vector chain = new Vector(); + while (extendsDef != null && !chain.contains(extendsDef)) { + chain.addElement(extendsDef); + extendsDef = extendsDef.getExtends(); + } + if (baseDef != null && getInherit()) { + chain.addElement(baseDef); + } + ProcessorDef[] defaultProviders = new ProcessorDef[chain.size()]; + chain.copyInto(defaultProviders); + return defaultProviders; + } + /** + * Gets the ProcessorDef specified by the extends attribute + * + * @return Base ProcessorDef, null if extends is not specified + * @throws BuildException + * if reference is not same type object + */ + public ProcessorDef getExtends() throws BuildException { + if (extendsRef != null) { + Object obj = extendsRef.getReferencedObject(getProject()); + if (!getClass().isInstance(obj)) { + throw new BuildException("Referenced object " + + extendsRef.getRefId() + " not correct type, is " + + obj.getClass().getName() + " should be " + + getClass().getName()); + } + return (ProcessorDef) obj; + } + return null; + } + /** + * Gets the inherit attribute. If the inherit value is true, this processor + * definition will inherit default values from the containing cc element. + * + * @return if true then properties from the containing element are + * used. + */ + public final boolean getInherit() { + return inherit; + } + public boolean getLibtool() { + if (libtool != null) { + return libtool.booleanValue(); + } + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).getLibtool(); + } + ProcessorDef extendsDef = getExtends(); + if (extendsDef != null) { + return extendsDef.getLibtool(); + } + return false; + } + /** + * Obtains the appropriate processor (compiler, linker) + * + * @return processor + */ + protected Processor getProcessor() { + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).getProcessor(); + } + // + // if a processor has not been explicitly set + // then may be set by an extended definition + if (processor == null) { + ProcessorDef extendsDef = getExtends(); + if (extendsDef != null) { + return extendsDef.getProcessor(); + } + } + return processor; + } + + /** + * Obtains the appropriate processor (compiler, linker) based on the + * LinkType. + * + * @return processor + */ + protected Processor getProcessor(LinkType linkType) { + // by default ignore the linkType. + return getProcessor(); + } + /** + * Gets a boolean value indicating whether all targets must be rebuilt + * regardless of dependency analysis. + * + * @param defaultProviders + * array of ProcessorDef's in descending priority + * @param index + * index to first element in array that should be considered + * @return true if all targets should be rebuilt. + */ + public boolean getRebuild(ProcessorDef[] defaultProviders, int index) { + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).getRebuild(defaultProviders, index); + } + if (rebuild != null) { + return rebuild.booleanValue(); + } else { + if (defaultProviders != null && index < defaultProviders.length) { + return defaultProviders[index].getRebuild(defaultProviders, + index + 1); + } + } + return false; + } + /** + * Returns true if the processor definition contains embedded file set + * definitions + * + * @return true if processor definition contains embedded filesets + */ + public boolean hasFileSets() { + if (isReference()) { + return ((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).hasFileSets(); + } + return srcSets.size() > 0; + } + /** + * Determine if this def should be used. + * + * Definition will be active if the "if" variable (if specified) is set and + * the "unless" variable (if specified) is not set and that all reference + * or extended definitions are active + * + * @return true if processor is active + * @throws IllegalStateException + * if not properly initialized + * @throws BuildException + * if "if" or "unless" variable contains suspicious values + * "false" or "no" which indicates possible confusion + */ + public boolean isActive() throws BuildException, IllegalStateException { + Project project = getProject(); + if (!CUtil.isActive(project, ifProp, unlessProp)) { + return false; + } + if (isReference()) { + if (!((ProcessorDef) getCheckedRef(ProcessorDef.class, + "ProcessorDef")).isActive()) { + return false; + } + } + // + // walk through any extended definitions + // + ProcessorDef[] defaultProviders = getDefaultProviders(null); + for (int i = 0; i < defaultProviders.length; i++) { + if (!defaultProviders[i].isActive()) { + return false; + } + } + return true; + } + /** + * Sets the class name for the adapter. Use the "name" attribute when the + * tool is supported. + * + * @param className + * full class name + * + */ + public void setClassname(String className) throws BuildException { + Object proc = null; + try { + Class implClass = ProcessorDef.class.getClassLoader().loadClass( + className); + try { + Method getInstance = implClass.getMethod("getInstance", + new Class[0]); + proc = getInstance.invoke(null, new Object[0]); + } catch (Exception ex) { + proc = implClass.newInstance(); + } + } catch (Exception ex) { + throw new BuildException(ex); + } + setProcessor((Processor) proc); + } + /** + * If set true, all targets will be built for debugging. + * + * @param debug + * true if targets should be built for debugging + * @throws BuildException + * if processor definition is a reference + */ + public void setDebug(boolean debug) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + this.debug = booleanValueOf(debug); + } + /** + * Sets a description of the current data type. + */ + public void setDescription(String desc) { + super.setDescription(desc); + } + /** + * Specifies that this element extends the element with id attribute with a + * matching value. The configuration will be constructed from the settings + * of this element, element referenced by extends, and the containing cc + * element. + * + * @param extendsRef + * Reference to the extended processor definition. + * @throws BuildException + * if this processor definition is a reference + */ + public void setExtends(Reference extendsRef) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + this.extendsRef = extendsRef; + } + /** + * Sets an id that can be used to reference this element. + * + * @param id + * id + */ + public void setId(String id) { + // + // this is actually accomplished by a different + // mechanism, but we can document it + // + } + /** + * Sets the property name for the 'if' condition. + * + * The configuration will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * name of property + */ + public void setIf(String propName) { + ifProp = propName; + } + /** + * If inherit has the default value of true, defines, includes and other + * settings from the containing cc element will be inherited. + * + * @param inherit + * new value + * @throws BuildException + * if processor definition is a reference + */ + public void setInherit(boolean inherit) throws BuildException { + if (isReference()) { + throw super.tooManyAttributes(); + } + this.inherit = inherit; + } + /** + * Set use of libtool. + * + * If set to true, the "libtool " will be prepended to the command line + * + * @param libtool + * If true, use libtool. + */ + public void setLibtool(boolean libtool) { + if (isReference()) { + throw tooManyAttributes(); + } + this.libtool = booleanValueOf(libtool); + } + /** + * Do not propagate old environment when new environment variables are + * specified. + */ + public void setNewenvironment(boolean newenv) { + newEnvironment = newenv; + } + /** + * Sets the processor + * + * @param processor + * processor, may not be null. + * @throws BuildException + * if ProcessorDef is a reference + * @throws NullPointerException + * if processor is null + */ + protected void setProcessor(Processor processor) throws BuildException, + NullPointerException { + if (processor == null) { + throw new NullPointerException("processor"); + } + if (isReference()) { + throw super.tooManyAttributes(); + } + if (env == null && !newEnvironment) { + this.processor = processor; + } else { + this.processor = processor.changeEnvironment(newEnvironment, env); + } + } + /** + * If set true, all targets will be unconditionally rebuilt. + * + * @param rebuild + * if true, rebuild all targets. + * @throws BuildException + * if processor definition is a reference + */ + public void setRebuild(boolean rebuild) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + this.rebuild = booleanValueOf(rebuild); + } + /** + * Specifies that this element should behave as if the content of the + * element with the matching id attribute was inserted at this location. If + * specified, no other attributes or child content should be specified, + * other than "if", "unless" and "description". + * + * @param ref + * Reference to other element + * + */ + public void setRefid(org.apache.tools.ant.types.Reference ref) { + super.setRefid(ref); + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the configuration will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessProp = propName; + } + /** + * This method calls the FileVistor's visit function for every file in the + * processors definition + * + * @param visitor + * object whose visit method is called for every file + */ + public void visitFiles(FileVisitor visitor) { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException( + "project must be set before this call"); + } + if (isReference()) { + ((ProcessorDef) getCheckedRef(ProcessorDef.class, "ProcessorDef")) + .visitFiles(visitor); + } + // + // if this processor extends another, + // visit its files first + // + ProcessorDef extendsDef = getExtends(); + if (extendsDef != null) { + extendsDef.visitFiles(visitor); + } + + for (int i = 0; i < srcSets.size(); i++) { + ConditionalFileSet srcSet = (ConditionalFileSet) srcSets + .elementAt(i); + if (srcSet.isActive()) { + // Find matching source files + DirectoryScanner scanner = srcSet.getDirectoryScanner(p); + // Check each source file - see if it needs compilation + String[] fileNames = scanner.getIncludedFiles(); + File parentDir = scanner.getBasedir(); + for (int j = 0; j < fileNames.length; j++) { + String currentFile = fileNames[j]; + visitor.visit(parentDir, currentFile); + } + } + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java new file mode 100644 index 0000000..9096183 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java @@ -0,0 +1,47 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import net.sf.antcontrib.cpptasks.compiler.Processor; +/** + * One entry in the arrays used by the CompilerEnum and LinkerEnum classes. + * + * @author Curt Arnold + * @see CompilerEnum + * @see LinkerEnum + * + */ +public class ProcessorEnumValue { + public static String[] getValues(ProcessorEnumValue[] processors) { + String[] values = new String[processors.length]; + for (int i = 0; i < processors.length; i++) { + values[i] = processors[i].getName(); + } + return values; + } + private String name; + private Processor processor; + public ProcessorEnumValue(String name, Processor processor) { + this.name = name; + this.processor = processor; + } + public String getName() { + return name; + } + public Processor getProcessor() { + return processor; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java new file mode 100644 index 0000000..1b0c613 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ProcessorParam.java @@ -0,0 +1,100 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +/******************************************************************************* + * Place class description here. + * + * @author inger + * @author + * + * @since + ******************************************************************************/ +public class ProcessorParam { + private String ifCond; + private String name; + private String unlessCond; + private String value; + public ProcessorParam() { + } + public String getName() { + return name; + } + public String getValue() { + return value; + } + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + */ + public boolean isActive(org.apache.tools.ant.Project p) { + if (value == null) { + return false; + } + if (ifCond != null && p.getProperty(ifCond) == null) { + return false; + } else if (unlessCond != null && p.getProperty(unlessCond) != null) { + return false; + } + return true; + } + /** + * Sets the property name for the 'if' condition. + * + * The argument will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + */ + public void setIf(String propName) { + ifCond = propName; + } + /** + * Specifies relative location of argument on command line. "start" will + * place argument at start of command line, "mid" will place argument after + * all "start" arguments but before filenames, "end" will place argument + * after filenames. + * + */ + public void setName(String name) { + this.name = name; + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the argument will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessCond = propName; + } + /** + * Specifies the string that should appear on the command line. The + * argument will be quoted if it contains embedded blanks. Use multiple + * arguments to avoid quoting. + * + */ + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java b/src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java new file mode 100644 index 0000000..6590098 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/RuntimeType.java @@ -0,0 +1,26 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import org.apache.tools.ant.types.EnumeratedAttribute; +/** + * Enumerated attribute with the values "dynamic" and "static", + */ +public class RuntimeType extends EnumeratedAttribute { + public String[] getValues() { + return new String[]{"dynamic", "static"}; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java b/src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java new file mode 100644 index 0000000..4ffd38f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/SourceHistory.java @@ -0,0 +1,51 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.IOException; +/** + * The history of a source file used to build a target + * + * @author Curt Arnold + */ +public final class SourceHistory { + private/* final */long lastModified; + private/* final */String relativePath; + /** + * Constructor + */ + public SourceHistory(String relativePath, long lastModified) { + if (relativePath == null) { + throw new NullPointerException("relativePath"); + } + this.relativePath = relativePath; + this.lastModified = lastModified; + } + public String getAbsolutePath(File baseDir) { + try { + return new File(baseDir, relativePath).getCanonicalPath(); + } catch (IOException ex) { + } + return relativePath; + } + public long getLastModified() { + return lastModified; + } + public String getRelativePath() { + return relativePath; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java new file mode 100644 index 0000000..19dd207 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/SubsystemEnum.java @@ -0,0 +1,34 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import org.apache.tools.ant.types.EnumeratedAttribute; +/** + * Enumeration of supported subsystems + * + * @author Curt Arnold + * + */ +public final class SubsystemEnum extends EnumeratedAttribute { + private final static String[] values = new String[]{"gui", "console", + "other"}; + public SubsystemEnum() { + setValue("gui"); + } + public String[] getValues() { + return (String[]) values.clone(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java new file mode 100644 index 0000000..70263ad --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetDef.java @@ -0,0 +1,228 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; + +/** + * Information on the execution platforms for the generated code. + * (Non-functional prototype) + * + */ +public final class TargetDef + extends DataType { + /** + * if property. + */ + private String ifCond; + + /** + * unless property. + */ + private String unlessCond; + + /** + * cpu. + * + */ + private CPUEnum cpu; + + /** + * architecture. + * + */ + private ArchEnum arch; + + /** + * OS Family. + * + */ + private OSFamilyEnum osFamily; + + /** + * Constructor. + * + */ + public TargetDef() { + } + + /** + * Bogus method required for documentation generation. + */ + public void execute() { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + * @return true if active + */ + public boolean isActive() { + return CUtil.isActive(getProject(), ifCond, unlessCond); + } + + /** + * Sets a description of the current data type. + * @param desc description + */ + public void setDescription(final String desc) { + super.setDescription(desc); + } + + /** + * Sets an id that can be used to reference this element. + * + * @param id + * id + */ + public void setId(final String id) { + // + // this is actually accomplished by a different + // mechanism, but we can document it + // + } + + /** + * Sets the property name for the 'if' condition. + * + * The define will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public void setIf(final String propName) { + ifCond = propName; + } + + /** + * Specifies that this element should behave as if the content of the + * element with the matching id attribute was inserted at this location. If + * specified, no other attributes should be specified. + * @param r id of referenced target + */ + public void setRefid(final Reference r) { + super.setRefid(r); + } + + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the define will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(final String propName) { + unlessCond = propName; + } + + /** + * Gets cpu. + * @return cpu, may be null. + * + */ + public CPUEnum getCpu() { + if (isReference()) { + TargetDef refPlatform = (TargetDef) + getCheckedRef(TargetDef.class, + "TargetDef"); + return refPlatform.getCpu(); + } + return cpu; + } + + /** + * Gets arch. + * @return arch, may be null. + * + */ + public ArchEnum getArch() { + if (isReference()) { + TargetDef refPlatform = (TargetDef) + getCheckedRef(TargetDef.class, + "TargetDef"); + return refPlatform.getArch(); + } + return arch; + } + + /** + * Gets operating system family. + * @return os family, may be null. + * + */ + public OSFamilyEnum getOsfamily() { + if (isReference()) { + TargetDef refPlatform = (TargetDef) + getCheckedRef(TargetDef.class, + "TargetDef"); + return refPlatform.getOsfamily(); + } + return osFamily; + } + + /** + * Sets preferred cpu, but does not use cpu specific instructions. + * @param value new value + */ + public void setCpu(final CPUEnum value) { + if (isReference()) { + throw tooManyAttributes(); + } + cpu = value; + } + + /** + * Sets cpu architecture, compiler may use cpu specific instructions. + * @param value new value + */ + public void setArch(final ArchEnum value) { + if (isReference()) { + throw tooManyAttributes(); + } + if (cpu != null) { + throw tooManyAttributes(); + } + arch = value; + } + + /** + * Sets operating system family. + * @param value new value + */ + public void setOsfamily(final OSFamilyEnum value) { + if (isReference()) { + throw tooManyAttributes(); + } + if (cpu != null) { + throw tooManyAttributes(); + } + osFamily = value; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java new file mode 100644 index 0000000..b797170 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistory.java @@ -0,0 +1,58 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +/** + * A description of a file built or to be built + */ +public final class TargetHistory { + private/* final */String config; + private/* final */String output; + private/* final */long outputLastModified; + private/* final */SourceHistory[] sources; + /** + * Constructor from build step + */ + public TargetHistory(String config, String output, long outputLastModified, + SourceHistory[] sources) { + if (config == null) { + throw new NullPointerException("config"); + } + if (sources == null) { + throw new NullPointerException("source"); + } + if (output == null) { + throw new NullPointerException("output"); + } + this.config = config; + this.output = output; + this.outputLastModified = outputLastModified; + this.sources = (SourceHistory[]) sources.clone(); + } + public String getOutput() { + return output; + } + public long getOutputLastModified() { + return outputLastModified; + } + public String getProcessorConfiguration() { + return config; + } + public SourceHistory[] getSources() { + SourceHistory[] clone = (SourceHistory[]) sources.clone(); + return clone; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java new file mode 100644 index 0000000..bdab94c --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetHistoryTable.java @@ -0,0 +1,430 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; + +import org.apache.tools.ant.BuildException; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; +/** + * A history of the compiler and linker settings used to build the files in the + * same directory as the history. + * + * @author Curt Arnold + */ +public final class TargetHistoryTable { + /** + * This class handles populates the TargetHistory hashtable in response to + * SAX parse events + */ + private class TargetHistoryTableHandler extends DefaultHandler { + private final File baseDir; + private String config; + private final Hashtable history; + private String output; + private long outputLastModified; + private final Vector sources = new Vector(); + /** + * Constructor + * + * @param history + * hashtable of TargetHistory keyed by output name + * @param outputFiles + * existing files in output directory + */ + private TargetHistoryTableHandler(Hashtable history, File baseDir) { + this.history = history; + config = null; + output = null; + this.baseDir = baseDir; + } + public void endElement(String namespaceURI, String localName, + String qName) throws SAXException { + // + // if then + // create TargetHistory object and add to hashtable + // if corresponding output file exists and + // has the same timestamp + // + if (qName.equals("target")) { + if (config != null && output != null) { + File existingFile = new File(baseDir, output); + // + // if the corresponding files doesn't exist or has a + // different + // modification time, then discard this record + if (existingFile.exists()) { + // + // would have expected exact time stamps + // but have observed slight differences + // in return value for multiple evaluations of + // lastModified(). Check if times are within + // a second + long existingLastModified = existingFile.lastModified(); + if (!CUtil.isSignificantlyBefore(existingLastModified, outputLastModified) + && !CUtil.isSignificantlyAfter(existingLastModified, outputLastModified)) { + SourceHistory[] sourcesArray = new SourceHistory[sources + .size()]; + sources.copyInto(sourcesArray); + TargetHistory targetHistory = new TargetHistory( + config, output, outputLastModified, + sourcesArray); + history.put(output, targetHistory); + } + } + } + output = null; + sources.setSize(0); + } else { + // + // reset config so targets not within a processor element + // don't pick up a previous processors signature + // + if (qName.equals("processor")) { + config = null; + } + } + } + /** + * startElement handler + */ + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) throws SAXException { + // + // if sourceElement + // + if (qName.equals("source")) { + String sourceFile = atts.getValue("file"); + long sourceLastModified = Long.parseLong(atts + .getValue("lastModified"), 16); + sources.addElement(new SourceHistory(sourceFile, + sourceLastModified)); + } else { + // + // if element, + // grab file name and lastModified values + // TargetHistory object will be created in endElement + // + if (qName.equals("target")) { + sources.setSize(0); + output = atts.getValue("file"); + outputLastModified = Long.parseLong(atts + .getValue("lastModified"), 16); + } else { + // + // if element, + // grab signature attribute + // + if (qName.equals("processor")) { + config = atts.getValue("signature"); + } + } + } + } + } + /** Flag indicating whether the cache should be written back to file. */ + private boolean dirty; + /** + * a hashtable of TargetHistory's keyed by output file name + */ + private final Hashtable history = new Hashtable(); + /** The file the cache was loaded from. */ + private/* final */File historyFile; + private/* final */File outputDir; + private String outputDirPath; + /** + * Creates a target history table from history.xml in the output directory, + * if it exists. Otherwise, initializes the history table empty. + * + * @param task + * task used for logging history load errors + * @param outputDir + * output directory for task + */ + public TargetHistoryTable(CCTask task, File outputDir) + throws BuildException { + if (outputDir == null) { + throw new NullPointerException("outputDir"); + } + if (!outputDir.isDirectory()) { + throw new BuildException("Output directory is not a directory"); + } + if (!outputDir.exists()) { + throw new BuildException("Output directory does not exist"); + } + this.outputDir = outputDir; + try { + outputDirPath = outputDir.getCanonicalPath(); + } catch (IOException ex) { + outputDirPath = outputDir.toString(); + } + // + // load any existing history from file + // suppressing any records whose corresponding + // file does not exist, is zero-length or + // last modified dates differ + historyFile = new File(outputDir, "history.xml"); + if (historyFile.exists()) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(false); + try { + SAXParser parser = factory.newSAXParser(); + parser.parse(historyFile, new TargetHistoryTableHandler( + history, outputDir)); + } catch (Exception ex) { + // + // a failure on loading this history is not critical + // but should be logged + task.log("Error reading history.xml: " + ex.toString()); + } + } else { + // + // create empty history file for identifying new files by last + // modified + // timestamp comperation (to compare with + // System.currentTimeMillis() don't work on Unix, because it + // maesure timestamps only in seconds). + // + try { + FileOutputStream outputStream = new FileOutputStream( + historyFile); + byte[] historyElement = new byte[]{0x3C, 0x68, 0x69, 0x73, + 0x74, 0x6F, 0x72, 0x79, 0x2F, 0x3E}; + outputStream.write(historyElement); + outputStream.close(); + } catch (IOException ex) { + throw new BuildException("Can't create history file", ex); + } + } + } + public void commit() throws IOException { + // + // if not dirty, no need to update file + // + if (dirty) { + // + // build (small) hashtable of config id's in history + // + Hashtable configs = new Hashtable(20); + Enumeration elements = history.elements(); + while (elements.hasMoreElements()) { + TargetHistory targetHistory = (TargetHistory) elements + .nextElement(); + String configId = targetHistory.getProcessorConfiguration(); + if (configs.get(configId) == null) { + configs.put(configId, configId); + } + } + FileOutputStream outStream = new FileOutputStream(historyFile); + OutputStreamWriter outWriter; + // + // early VM's don't support UTF-8 encoding + // try and fallback to the default encoding + // otherwise + String encodingName = "UTF-8"; + try { + outWriter = new OutputStreamWriter(outStream, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + outWriter = new OutputStreamWriter(outStream); + encodingName = outWriter.getEncoding(); + } + BufferedWriter writer = new BufferedWriter(outWriter); + writer.write("\n"); + writer.write("\n"); + StringBuffer buf = new StringBuffer(200); + Enumeration configEnum = configs.elements(); + while (configEnum.hasMoreElements()) { + String configId = (String) configEnum.nextElement(); + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + elements = history.elements(); + while (elements.hasMoreElements()) { + TargetHistory targetHistory = (TargetHistory) elements + .nextElement(); + if (targetHistory.getProcessorConfiguration().equals( + configId)) { + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + SourceHistory[] sourceHistories = targetHistory + .getSources(); + for (int i = 0; i < sourceHistories.length; i++) { + buf.setLength(0); + buf.append(" \n"); + writer.write(buf.toString()); + } + writer.write(" \n"); + } + } + writer.write(" \n"); + } + writer.write("\n"); + writer.close(); + dirty = false; + } + } + public TargetHistory get(String configId, String outputName) { + TargetHistory targetHistory = (TargetHistory) history.get(outputName); + if (targetHistory != null) { + if (!targetHistory.getProcessorConfiguration().equals(configId)) { + targetHistory = null; + } + } + return targetHistory; + } + public void markForRebuild(Hashtable targetInfos) { + Enumeration targetInfoEnum = targetInfos.elements(); + while (targetInfoEnum.hasMoreElements()) { + markForRebuild((TargetInfo) targetInfoEnum.nextElement()); + } + } + public void markForRebuild(TargetInfo targetInfo) { + // + // if it must already be rebuilt, no need to check further + // + if (!targetInfo.getRebuild()) { + TargetHistory history = get(targetInfo.getConfiguration() + .toString(), targetInfo.getOutput().getName()); + if (history == null) { + targetInfo.mustRebuild(); + } else { + SourceHistory[] sourceHistories = history.getSources(); + File[] sources = targetInfo.getSources(); + if (sourceHistories.length != sources.length) { + targetInfo.mustRebuild(); + } else { + Hashtable sourceMap = new Hashtable(sources.length); + for (int i = 0; i < sources.length; i++) { + try { + sourceMap.put(sources[i].getCanonicalPath(), sources[i]); + } catch(IOException ex) { + sourceMap.put(sources[i].getAbsolutePath(), sources[i]); + } + } + for (int i = 0; i < sourceHistories.length; i++) { + // + // relative file name, must absolutize it on output + // directory + // + String absPath = sourceHistories[i].getAbsolutePath(outputDir); + File match = (File) sourceMap.get(absPath); + if (match != null) { + try { + match = (File) sourceMap.get(new File(absPath).getCanonicalPath()); + } catch(IOException ex) { + targetInfo.mustRebuild(); + break; + } + } + if (match == null || match.lastModified() != sourceHistories[i].getLastModified()) { + targetInfo.mustRebuild(); + break; + } + } + } + } + } + } + public void update(ProcessorConfiguration config, String[] sources, VersionInfo versionInfo) { + String configId = config.getIdentifier(); + String[] onesource = new String[1]; + String[] outputNames; + for (int i = 0; i < sources.length; i++) { + onesource[0] = sources[i]; + outputNames = config.getOutputFileNames(sources[i], versionInfo); + for (int j = 0; j < outputNames.length; j++) { + update(configId, outputNames[j], onesource); + } + } + } + private void update(String configId, String outputName, String[] sources) { + File outputFile = new File(outputDir, outputName); + // + // if output file doesn't exist or predates the start of the + // compile step (most likely a compilation error) then + // do not write add a history entry + // + if (outputFile.exists() && + !CUtil.isSignificantlyBefore(outputFile.lastModified(), historyFile.lastModified())) { + dirty = true; + history.remove(outputName); + SourceHistory[] sourceHistories = new SourceHistory[sources.length]; + for (int i = 0; i < sources.length; i++) { + File sourceFile = new File(sources[i]); + long lastModified = sourceFile.lastModified(); + String relativePath = CUtil.getRelativePath(outputDirPath, + sourceFile); + sourceHistories[i] = new SourceHistory(relativePath, + lastModified); + } + TargetHistory newHistory = new TargetHistory(configId, outputName, + outputFile.lastModified(), sourceHistories); + history.put(outputName, newHistory); + } + } + public void update(TargetInfo linkTarget) { + File outputFile = linkTarget.getOutput(); + String outputName = outputFile.getName(); + // + // if output file doesn't exist or predates the start of the + // compile or link step (most likely a compilation error) then + // do not write add a history entry + // + if (outputFile.exists() + && !CUtil.isSignificantlyBefore(outputFile.lastModified(),historyFile.lastModified())) { + dirty = true; + history.remove(outputName); + SourceHistory[] sourceHistories = linkTarget + .getSourceHistories(outputDirPath); + TargetHistory newHistory = new TargetHistory(linkTarget + .getConfiguration().getIdentifier(), outputName, outputFile + .lastModified(), sourceHistories); + history.put(outputName, newHistory); + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java new file mode 100644 index 0000000..8fd5bb4 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetInfo.java @@ -0,0 +1,127 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; + +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +/** + * A description of a file built or to be built + */ +public final class TargetInfo { + private static final File[] emptyFileArray = new File[0]; + private/* final */ProcessorConfiguration config; + private/* final */File output; + private boolean rebuild; + private/* final */File[] sources; + private File[] sysSources; + public TargetInfo(ProcessorConfiguration config, File[] sources, + File[] sysSources, File output, boolean rebuild) { + if (config == null) { + throw new NullPointerException("config"); + } + if (sources == null) { + throw new NullPointerException("sources"); + } + if (output == null) { + throw new NullPointerException("output"); + } + this.config = config; + this.sources = (File[]) sources.clone(); + if (sysSources == null) { + this.sysSources = emptyFileArray; + } else { + this.sysSources = (File[]) sysSources.clone(); + } + this.output = output; + this.rebuild = rebuild; + // + // if the output doesn't exist, must rebuild it + // + if (!output.exists()) { + rebuild = true; + } + } + public String[] getAllSourcePaths() { + String[] paths = new String[sysSources.length + sources.length]; + for (int i = 0; i < sysSources.length; i++) { + paths[i] = sysSources[i].toString(); + } + int offset = sysSources.length; + for (int i = 0; i < sources.length; i++) { + paths[offset + i] = sources[i].toString(); + } + return paths; + } + public File[] getAllSources() { + File[] allSources = new File[sources.length + sysSources.length]; + for (int i = 0; i < sysSources.length; i++) { + allSources[i] = sysSources[i]; + } + int offset = sysSources.length; + for (int i = 0; i < sources.length; i++) { + allSources[i + offset] = sources[i]; + } + return allSources; + } + public ProcessorConfiguration getConfiguration() { + return config; + } + public File getOutput() { + return output; + } + public boolean getRebuild() { + return rebuild; + } + /** + * Returns an array of SourceHistory objects (contains relative path and + * last modified time) for the source[s] of this target + */ + public SourceHistory[] getSourceHistories(String basePath) { + SourceHistory[] histories = new SourceHistory[sources.length]; + for (int i = 0; i < sources.length; i++) { + String relativeName = CUtil.getRelativePath(basePath, sources[i]); + long lastModified = sources[i].lastModified(); + histories[i] = new SourceHistory(relativeName, lastModified); + } + return histories; + } + public String[] getSourcePaths() { + String[] paths = new String[sources.length]; + for (int i = 0; i < sources.length; i++) { + paths[i] = sources[i].toString(); + } + return paths; + } + public File[] getSources() { + File[] clone = (File[]) sources.clone(); + return clone; + } + public String[] getSysSourcePaths() { + String[] paths = new String[sysSources.length]; + for (int i = 0; i < sysSources.length; i++) { + paths[i] = sysSources[i].toString(); + } + return paths; + } + public File[] getSysSources() { + File[] clone = (File[]) sysSources.clone(); + return clone; + } + public void mustRebuild() { + this.rebuild = true; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java b/src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java new file mode 100644 index 0000000..9260f77 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/TargetMatcher.java @@ -0,0 +1,120 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.util.Hashtable; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.LinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; + +import org.apache.tools.ant.BuildException; +/** + * This class matches each visited file with an appropriate compiler + * + * @author Curt Arnold + */ +public final class TargetMatcher implements FileVisitor { + private LinkerConfiguration linker; + private Vector objectFiles; + private File outputDir; + private ProcessorConfiguration[] processors; + private final File sourceFiles[] = new File[1]; + private Hashtable targets; + private VersionInfo versionInfo; + private CCTask task; + public TargetMatcher(CCTask task, File outputDir, + ProcessorConfiguration[] processors, LinkerConfiguration linker, + Vector objectFiles, Hashtable targets, + VersionInfo versionInfo) { + this.task = task; + this.outputDir = outputDir; + this.processors = processors; + this.targets = targets; + this.linker = linker; + this.objectFiles = objectFiles; + this.versionInfo = versionInfo; + } + public void visit(File parentDir, String filename) throws BuildException { + File fullPath = new File(parentDir, filename); + // + // see if any processor wants to bid + // on this one + ProcessorConfiguration selectedCompiler = null; + int bid = 0; + if (processors != null) { + for (int k = 0; k < processors.length; k++) { + int newBid = processors[k].bid(fullPath.toString()); + if (newBid > bid) { + bid = newBid; + selectedCompiler = processors[k]; + } + } + } + // + // no processor interested in file + // log diagnostic message + if (bid <= 0) { + if (linker != null) { + int linkerbid = linker.bid(filename); + if (linkerbid > 0) { + objectFiles.addElement(fullPath); + if (linkerbid == 1) { + task.log("Unrecognized file type " + fullPath.toString() + + " will be passed to linker"); + } + } + } + } else { + // + // get output file name + // + String[] outputFileNames = selectedCompiler + .getOutputFileNames(filename, versionInfo); + sourceFiles[0] = fullPath; + // + // if there is some output for this task + // (that is a source file and not an header file) + // + for (int i = 0; i < outputFileNames.length; i++) { + // + // see if the same output file has already been registered + // + TargetInfo previousTarget = (TargetInfo) targets + .get(outputFileNames[i]); + if (previousTarget == null) { + targets.put(outputFileNames[i], new TargetInfo( + selectedCompiler, sourceFiles, null, new File( + outputDir, outputFileNames[i]), + selectedCompiler.getRebuild())); + } else { + if (!previousTarget.getSources()[0].equals(sourceFiles[0])) { + StringBuffer builder = new StringBuffer( + "Output filename conflict: "); + builder.append(outputFileNames[i]); + builder.append(" would be produced from "); + builder.append(previousTarget.getSources()[0] + .toString()); + builder.append(" and "); + builder.append(filename); + throw new BuildException(builder.toString()); + } + } + } + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java b/src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java new file mode 100644 index 0000000..92cfeb0 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/VersionInfo.java @@ -0,0 +1,671 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; + +/** + * Version Information. + * + * This information is applied in a platform specific manner + * to embed version information into executable images. This + * behavior is new and subject to change. + * + * On the Microsoft Windows platform, a resource is generated and added + * to the set of files to be compiled. A resource compiler must + * be specified to compile the generated file. + * + * On Unix platforms, versioninfo is currently not used. + * Future versions may append fileversion to the output file name, + * use compatibility version for -soname and possibly create + * symbolic links. + */ +public final class VersionInfo extends DataType { + /** + * if property. + */ + private String ifCond; + /** + * unless property. + */ + private String unlessCond; + + /** + * extends property. + */ + private Reference extendsRef; + + /** + * file version. + * + */ + private String fileVersion; + /** + * Product version. + * + */ + private String productVersion; + /** + * file language. + * + */ + private String language; + + /** + * comments. + * + */ + private String fileComments; + /** + * Company name. + * + */ + private String companyName; + /** + * Description. + * + */ + private String fileDescription; + /** + * internal name. + */ + private String internalName; + /** + * legal copyright. + * + */ + private String legalCopyright; + /** + * legal trademark. + * + */ + private String legalTrademarks; + /** + * original filename. + * + */ + private String originalFilename; + /** + * private build. + * + */ + private String privateBuild; + /** + * product name. + * + */ + private String productName; + /** + * Special build + */ + private String specialBuild; + /** + * compatibility version + * + */ + private String compatibilityVersion; + + /** + * prerease build. + * + */ + private Boolean prerelease; + + /** + * prerease build. + * + */ + private Boolean patched; + + + /** + * Constructor. + * + */ + public VersionInfo() { + } + + /** + * Private constructor for merge. + * @param stack list of version infos with most significant first. + */ + private VersionInfo(final Vector stack) { + VersionInfo source = null; + for(int i = stack.size() - 1; i >= 0; i--) { + source = (VersionInfo) stack.elementAt(i); + if (source.getIf() != null) { + ifCond = source.getIf(); + } + if (source.getUnless() != null) { + unlessCond = source.getUnless(); + } + if (source.getFileversion() != null) { + fileVersion = source.getFileversion(); + } + if (source.getProductversion() != null) { + productVersion = source.getProductversion(); + } + if (source.getLanguage() != null) { + language = source.getLanguage(); + } + if (source.getFilecomments() != null) { + fileComments = source.getFilecomments(); + } + if (source.getCompanyname() != null) { + companyName = source.getCompanyname(); + } + if (source.getFiledescription() != null) { + fileDescription = source.getFiledescription(); + } + if (source.getInternalname() != null) { + internalName = source.getInternalname(); + } + if (source.getLegalcopyright() != null) { + legalCopyright = source.getLegalcopyright(); + } + if (source.getLegaltrademarks() != null) { + legalTrademarks = source.getLegaltrademarks(); + } + if (source.getOriginalfilename() != null) { + originalFilename = source.getOriginalfilename(); + } + if (source.getPrivatebuild() != null) { + privateBuild = source.getPrivatebuild(); + } + if (source.getProductname() != null) { + productName = source.getProductname(); + } + if (source.getSpecialbuild() != null) { + specialBuild = source.getSpecialbuild(); + } + if (source.getCompatibilityversion() != null) { + compatibilityVersion = source.getCompatibilityversion(); + } + if (source.getPrerelease() != null) { + prerelease = source.getPrerelease(); + } + if (source.getPatched() != null) { + patched = source.getPatched(); + } + } + setProject(source.getProject()); + } + + /** + * Returns a VersionInfo that reflects any inherited version information. + * @return merged version information. + */ + public VersionInfo merge() { + if (isReference()) { + VersionInfo refVersion = (VersionInfo) + getCheckedRef(VersionInfo.class, + "VersionInfo"); + return refVersion.merge(); + } + Reference currentRef = this.getExtends(); + if (currentRef == null) { + return this; + } + Vector stack = new Vector(5); + stack.addElement(this); + while (currentRef != null) { + Object obj = currentRef.getReferencedObject(getProject()); + if (obj instanceof VersionInfo) { + VersionInfo current = (VersionInfo) obj; + if (current.isReference()) { + current = (VersionInfo) + current.getCheckedRef(VersionInfo.class, + "VersionInfo"); + } + if (stack.contains(current)) { + throw this.circularReference(); + } + stack.addElement(current); + currentRef = current.getExtends(); + } else { + throw new BuildException("Referenced element " + + currentRef.getRefId() + " is not a versioninfo."); + } + } + return new VersionInfo(stack); + } + /** + * Methods is required for documentation generation, throws + * exception if called. + * + * @throws org.apache.tools.ant.BuildException if called + */ + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + * + * @exception BuildException + * throws build exception if name is not set + */ + public final boolean isActive() throws BuildException { + return CUtil.isActive(getProject(), ifCond, unlessCond); + } + /** + * Sets an id that can be used to reference this element. + * + * @param id + * id + */ + public void setId(String id) { + // + // this is actually accomplished by a different + // mechanism, but we can document it + // + } + + public Reference getExtends() { + return this.extendsRef; + } + /** + * Specifies that this element extends the element with id attribute with a + * matching value. The configuration will be constructed from the settings + * of this element, element referenced by extends, and the containing cc + * element. + * + * @param extendsRef + * Reference to the extended processor definition. + * @throws BuildException + * if this processor definition is a reference + */ + public void setExtends(Reference extendsRef) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + this.extendsRef = extendsRef; + } + + /** + * Gets if property name. + * @return property name, may be null. + */ + public final String getIf() { + return ifCond; + } + /** + * Sets the property name for the 'if' condition. + * + * The define will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public final void setIf(String propName) { + if (isReference()) { + throw tooManyAttributes(); + } + ifCond = propName; + } + /** + * Specifies that this element should behave as if the content of the + * element with the matching id attribute was inserted at this location. If + * specified, no other attributes should be specified. + * + */ + public void setRefid(Reference r) throws BuildException { + super.setRefid(r); + } + /** + * Gets if property name. + * @return property name, may be null. + */ + public final String getUnless() { + return unlessCond; + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the define will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public final void setUnless(String propName) { + if (isReference()) { + throw tooManyAttributes(); + } + unlessCond = propName; + } + /** + * Gets file version. + * @return file version, may be null. + * + */ + public String getFileversion() { + return fileVersion; + } + /** + * Gets Product version. + * @return product version, may be null + */ + public String getProductversion() { + return productVersion; + } + /** + * Gets compatibility version. + * @return compatibility version, may be null + */ + public String getCompatibilityversion() { + return compatibilityVersion; + } + /** + * Gets file language, should be an IETF RFC 3066 identifier, for example, en-US. + * @return language, may be null. + */ + public String getLanguage() { + return language; + } + + /** + * Gets comments. + * @return comments, may be null. + */ + public String getFilecomments() { + return fileComments; + } + /** + * Gets Company name. + * @return company name, may be null. + */ + public String getCompanyname() { + return companyName; + } + /** + * Gets Description. + * @return description, may be null. + */ + public String getFiledescription() { + return fileDescription; + } + /** + * Gets internal name. + * @return internal name, may be null. + */ + public String getInternalname() { + return internalName; + } + /** + * Gets legal copyright. + * @return legal copyright, may be null. + */ + public String getLegalcopyright() { + return legalCopyright; + } + /** + * Gets legal trademark. + * @return legal trademark, may be null; + */ + public String getLegaltrademarks() { + return legalTrademarks; + } + /** + * Gets original filename. + * @return original filename, may be null. + */ + public String getOriginalfilename() { + return originalFilename; + } + /** + * Gets private build. + * @return private build, may be null. + */ + public String getPrivatebuild() { + return privateBuild; + } + /** + * Gets prerelease. + * @return prerelease, may be null. + */ + public Boolean getPrerelease() { + return prerelease; + } + /** + * Gets patched. + * @return patched, may be null. + */ + public Boolean getPatched() { + return patched; + } + /** + * Gets product name. + * @return product name, may be null. + */ + public String getProductname() { + return productName; + } + /** + * Special build + * @return special build, may be null. + */ + public String getSpecialbuild() { + return specialBuild; + } + + /** + * Sets file version. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setFileversion(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + fileVersion = value; + } + /** + * Sets product version. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setProductversion(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + productVersion = value; + } + /** + * Sets compatibility version. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setCompatibilityversion(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + compatibilityVersion = value; + } + /** + * Sets language. + * @param value new value, should be an IETF RFC 3066 language identifier. + * @throws BuildException if specified with refid + */ + public void setLanguage(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + language = value; + } + /** + * Sets comments. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setFilecomments(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + fileComments = value; + } + + /** + * Sets file description. + * @param value new value + */ + public void setFiledescription(String value) { + if (isReference()) { + throw tooManyAttributes(); + } + fileDescription = value; + } + + /** + * Sets company name. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setCompanyname(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + companyName = value; + } + + + /** + * Sets internal name. Internal name will automatically be + * specified from build step, only set this value if + * intentionally overriding that value. + * + * @param value new value + * @throws BuildException if specified with refid + */ + public void setInternalname(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + internalName = value; + } + + /** + * Sets legal copyright. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setLegalcopyright(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + legalCopyright = value; + } + /** + * Sets legal trademark. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setLegaltrademarks(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + legalTrademarks = value; + } + /** + * Sets original name. Only set this value if + * intentionally overriding the value from the build set. + * + * @param value new value + * @throws BuildException if specified with refid + */ + public void setOriginalfilename(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + originalFilename = value; + } + /** + * Sets private build. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setPrivatebuild(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + privateBuild = value; + } + /** + * Sets prerelease. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setPrerelease(boolean value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + if (value) { + prerelease = Boolean.TRUE; + } else { + prerelease = Boolean.FALSE; + } + } + /** + * Sets prerelease. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setPatched(boolean value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + if (value) { + patched = Boolean.TRUE; + } else { + patched = Boolean.FALSE; + } + } + /** + * Sets product name. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setProductname(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + productName= value; + } + /** + * Sets private build. + * @param value new value + * @throws BuildException if specified with refid + */ + public void setSpecialbuild(String value) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + specialBuild = value; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java new file mode 100644 index 0000000..6ba7438 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/WarningLevelEnum.java @@ -0,0 +1,40 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Enumerated attribute with the values "none", "severe", "default", + * "production", "diagnostic", and "aserror". + */ +public final class WarningLevelEnum extends EnumeratedAttribute { + /** + * Constructor. + * + */ + public WarningLevelEnum() { + setValue("default"); + } + /** + * Get allowable values. + * @return allowable values + */ + public String[] getValues() { + return new String[]{"none", "severe", "default", "production", + "diagnostic", "aserror"}; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java b/src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java new file mode 100644 index 0000000..c3a6807 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/PropertyListSerialization.java @@ -0,0 +1,235 @@ +/* + * Licensed to the Ant-Contrib Project under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The Ant-Contrib licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.apple; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import javax.xml.transform.Result; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.io.File; +import java.io.IOException; +import java.io.FileOutputStream; + +/** + * Static class that provides methods to serialize + * a Map to a Cocoa XML Property List. Does not currently support + * date or data elements. + */ +public final class PropertyListSerialization { + /** + * Private constructor. + */ + private PropertyListSerialization() { + + } + + /** + * Serializes a property list into a Cocoa XML Property List document. + * @param propertyList property list. + * @param file destination. + * @param comments comments to insert into document. + * @throws SAXException if exception during serialization. + * @throws TransformerConfigurationException if exception creating serializer. + */ + public static void serialize(final Map propertyList, + final List comments, + final File file) + throws IOException, SAXException, + TransformerConfigurationException { + SAXTransformerFactory sf = (SAXTransformerFactory) + SAXTransformerFactory.newInstance(); + TransformerHandler handler = sf.newTransformerHandler(); + + FileOutputStream os = new FileOutputStream(file); + StreamResult result = new StreamResult(os); + handler.setResult(result); + + handler.startDocument(); + for(Iterator iter = comments.iterator(); iter.hasNext();) { + char[] comment = String.valueOf(iter.next()).toCharArray(); + handler.comment(comment, 0, comment.length); + } + AttributesImpl attributes = new AttributesImpl(); + handler.startElement(null, "plist", "plist", attributes); + serializeMap(propertyList, handler); + handler.endElement(null, "plist", "plist"); + + handler.endDocument(); + } + + /** + * Serialize a map as a dict element. + * @param map map to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeMap(final Map map, + final ContentHandler handler) + throws SAXException { + AttributesImpl attributes = new AttributesImpl(); + handler.startElement(null, "dict", "dict", attributes); + + if (map.size() > 0) { + // + // need to output with sorted keys to maintain + // reproducability + // + Object[] keys = map.keySet().toArray(); + Arrays.sort(keys); + for(int i = 0; i < keys.length; i++) { + String key = String.valueOf(keys[i]); + handler.startElement(null, "key", "key", attributes); + handler.characters(key.toCharArray(), 0, key.length()); + handler.endElement(null, "key", "key"); + serializeObject(map.get(keys[i]), handler); + } + } + handler.endElement(null, "dict", "dict"); + } + + /** + * Serialize a list as an array element. + * @param list list to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeList(final List list, + final ContentHandler handler) + throws SAXException { + AttributesImpl attributes = new AttributesImpl(); + handler.startElement(null, "array", "array", attributes); + for(Iterator iter = list.iterator();iter.hasNext();) { + serializeObject(iter.next(), handler); + } + handler.endElement(null, "array", "array"); + } + + /** + * Creates an element with the specified tag name and character content. + * @param tag tag name. + * @param content character content. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeElement(final String tag, + final String content, + final ContentHandler handler) + throws SAXException { + AttributesImpl attributes = new AttributesImpl(); + handler.startElement(null, tag, tag, attributes); + handler.characters(content.toCharArray(), 0, content.length()); + handler.endElement(null, tag, tag); + } + + + /** + * Serialize a Number as an integer element. + * @param integer number to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeInteger(final Number integer, + final ContentHandler handler) + throws SAXException { + serializeElement("integer", String.valueOf(integer.longValue()), + handler); + } + + /** + * Serialize a Number as a real element. + * @param real number to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeReal(final Number real, + final ContentHandler handler) + throws SAXException { + serializeElement("real", + String.valueOf(real.doubleValue()), + handler); + } + + + /** + * Serialize a Boolean as a true or false element. + * @param val boolean to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeBoolean(final Boolean val, + final ContentHandler handler) + throws SAXException { + String tag = "false"; + if (val.booleanValue()) { + tag = "true"; + } + AttributesImpl attributes = new AttributesImpl(); + handler.startElement(null, tag, tag, attributes); + handler.endElement(null, tag, tag); + } + + /** + * Serialize a string as a string element. + * @param val string to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeString(final String val, + final ContentHandler handler) + throws SAXException { + serializeElement("string", + val, + handler); + } + + + /** + * Serialize an object using the best available element. + * @param obj object to serialize. + * @param handler destination of serialization events. + * @throws SAXException if exception during serialization. + */ + private static void serializeObject(final Object obj, + final ContentHandler handler) + throws SAXException { + if (obj instanceof Map) { + serializeMap((Map) obj, handler); + } else if (obj instanceof List) { + serializeList((List) obj, handler); + } else if (obj instanceof Number) { + if(obj instanceof Double + ||obj instanceof Float) { + serializeReal((Number) obj, handler); + } else { + serializeInteger((Number) obj, handler); + } + } else if (obj instanceof Boolean) { + serializeBoolean((Boolean) obj, handler); + } else { + serializeString(String.valueOf(obj), handler); + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java new file mode 100644 index 0000000..f901b4d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java @@ -0,0 +1,1016 @@ +/* + * + * Copyright 2004-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.apple; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; +import net.sf.antcontrib.cpptasks.ide.DependencyDef; +import net.sf.antcontrib.cpptasks.ide.ProjectDef; +import net.sf.antcontrib.cpptasks.ide.ProjectWriter; +import org.apache.tools.ant.BuildException; +import org.xml.sax.SAXException; + +import javax.xml.transform.TransformerConfigurationException; +import java.io.File; +import java.io.IOException; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + + +/** + * Writes a Apple Xcode 2.1+ project directory. XCode stores project + * configuration as a PropertyList. Though it will always write the project + * as a Cocoa Old-Style ASCII property list, it will read projects + * stored using Cocoa's XML Property List format. + */ +public final class XcodeProjectWriter + implements ProjectWriter { + + /** + * Constructor. + */ + public XcodeProjectWriter() { + } + + /** + * Writes a project definition file. + * + * @param fileName File name base, writer may append appropriate extension + * @param task cc task for which to write project + * @param projectDef project element + * @param targets compilation targets + * @param linkTarget link target + * @throws IOException if error writing project file + */ + public void writeProject(final File fileName, + final CCTask task, + final ProjectDef projectDef, + final List sources, + final Hashtable targets, + final TargetInfo linkTarget) throws IOException { + + File xcodeDir = new File(fileName + ".xcodeproj"); + if (!projectDef.getOverwrite() && xcodeDir.exists()) { + throw new BuildException("Not allowed to overwrite project file " + + xcodeDir.toString()); + } + + CommandLineCompilerConfiguration compilerConfig = + getBaseCompilerConfiguration(targets); + if (compilerConfig == null) { + throw new BuildException( + "Unable to find compilation target using GNU C++ compiler"); + } + + + CommandLineLinkerConfiguration linkerConfig = null; + if (linkTarget.getConfiguration() instanceof CommandLineLinkerConfiguration) { + linkerConfig = (CommandLineLinkerConfiguration) linkTarget.getConfiguration(); + } + + String projectName = projectDef.getName(); + if (projectName == null) { + projectName = fileName.getName(); + } + final String basePath = fileName.getAbsoluteFile().getParent(); + + xcodeDir.mkdir(); + + File xcodeProj = new File(xcodeDir, "project.pbxproj"); + + // + // create property list + // + Map propertyList = new HashMap(); + propertyList.put("archiveVersion", "1"); + propertyList.put("classes", new HashMap()); + propertyList.put("objectVersion", "42"); + Map objects = new HashMap(); + + final String sourceTree = ""; + + // + // add source files and source group to property list + // + List sourceGroupChildren = + addSources(objects, "SOURCE_ROOT", basePath, targets); + PBXObjectRef sourceGroup = + createPBXGroup("Source", sourceTree, sourceGroupChildren); + objects.put(sourceGroup.getID(), sourceGroup.getProperties()); + + + + + // + // add product to property list + // + PBXObjectRef product = addProduct(objects, linkTarget); + List productsList = new ArrayList(); + productsList.add(product); + PBXObjectRef productsGroup = + createPBXGroup("Products", sourceTree, productsList); + objects.put(productsGroup.getID(), productsGroup.getProperties()); + + // + // add documentation group to property list + // + PBXObjectRef documentationGroup = addDocumentationGroup(objects, sourceTree); + + // + // add main group containing source, products and documentation group + // + ArrayList groups = new ArrayList(3); + groups.add(sourceGroup); + groups.add(documentationGroup); + groups.add(productsGroup); + PBXObjectRef mainGroup = createPBXGroup(projectName, sourceTree, groups); + StringBuffer comments = new StringBuffer(); + for(Iterator iter = projectDef.getComments().iterator(); iter.hasNext();) { + comments.append(iter.next()); + } + if (comments.length() > 0) { + mainGroup.getProperties().put("comments", comments.toString()); + } + objects.put(mainGroup.getID(), mainGroup.getProperties()); + + // + // add project configurations + // + PBXObjectRef compilerConfigurations = + addProjectConfigurationList(objects, + basePath, + projectDef.getDependencies(), + compilerConfig, + linkerConfig); + + String projectDirPath = ""; + List projectTargets = new ArrayList(); + + // + // add project to property list + // + // + // Calculate path (typically several ../..) of the root directory + // (where build.xml lives) relative to the XCode project directory. + // XCode 3.0 will now prompt user to supply the value if not specified. + String projectRoot = CUtil.toUnixPath( + CUtil.getRelativePath(basePath, projectDef.getProject().getBaseDir())); + PBXObjectRef project = createPBXProject(compilerConfigurations, mainGroup, + projectDirPath, projectRoot, projectTargets); + objects.put(project.getID(), project.getProperties()); + + List frameworkBuildFiles = new ArrayList(); + for (Iterator iter = projectDef.getDependencies().iterator(); iter.hasNext();) { + DependencyDef dependency = (DependencyDef) iter.next(); + PBXObjectRef buildFile = addDependency(objects, project, groups, basePath, dependency); + if (buildFile != null) { + frameworkBuildFiles.add(buildFile); + } + } + // + // add description of native target (that is the executable or + // shared library) + // + PBXObjectRef nativeTarget = + addNativeTarget(objects, linkTarget, product, + projectName, sourceGroupChildren, frameworkBuildFiles); + projectTargets.add(nativeTarget); + + + + + + // + // finish up overall property list + // + propertyList.put("objects", objects); + propertyList.put("rootObject", project.getID()); + + + // + // write property list out to XML file + // + try { + PropertyListSerialization.serialize(propertyList, + projectDef.getComments(), xcodeProj); + } catch (TransformerConfigurationException ex) { + throw new IOException(ex.toString()); + } catch (SAXException ex) { + if (ex.getException() instanceof IOException) { + throw (IOException) ex.getException(); + } + throw new IOException(ex.toString()); + } + } + + + /** + * Adds a dependency to the object graph. + * @param objects + * @param project + * @param mainGroupChildren + * @param baseDir + * @param dependency + * @return PBXBuildFile to add to PBXFrameworksBuildPhase. + */ + private PBXObjectRef addDependency(final Map objects, + final PBXObjectRef project, + final List mainGroupChildren, + final String baseDir, + final DependencyDef dependency) { + if (dependency.getFile() != null) { + File xcodeDir = new File(dependency.getFile().getAbsolutePath() + ".xcodeproj"); + if (xcodeDir.exists()) { + PBXObjectRef xcodePrj = createPBXFileReference("SOURCE_ROOT", baseDir, xcodeDir); + mainGroupChildren.add(xcodePrj); + objects.put(xcodePrj.getID(), xcodePrj.getProperties()); + + int proxyType = 2; + PBXObjectRef proxy = createPBXContainerItemProxy( + xcodePrj, proxyType, dependency.getName()); + objects.put(proxy.getID(), proxy.getProperties()); + + PBXObjectRef referenceProxy = createPBXReferenceProxy(proxy, dependency); + objects.put(referenceProxy.getID(), referenceProxy.getProperties()); + + PBXObjectRef buildFile = createPBXBuildFile(referenceProxy, Collections.EMPTY_MAP); + objects.put(buildFile.getID(), buildFile.getProperties()); + + List productsChildren = new ArrayList(); + productsChildren.add(referenceProxy); + PBXObjectRef products = createPBXGroup("Products", "", productsChildren); + objects.put(products.getID(), products.getProperties()); + + Map projectReference = new HashMap(); + projectReference.put("ProductGroup", products); + projectReference.put("ProjectRef", xcodePrj); + + List projectReferences = (List) project.getProperties().get("ProjectReferences"); + if (projectReferences == null) { + projectReferences = new ArrayList(); + project.getProperties().put("ProjectReferences", projectReferences); + } + projectReferences.add(projectReference); + return buildFile; + } + } + return null; + } + + /** + * Add documentation group to map of objects. + * @param objects object map. + * @param sourceTree source tree description. + * @return documentation group. + */ + private PBXObjectRef addDocumentationGroup(final Map objects, + final String sourceTree) { + List productsList = new ArrayList(); + PBXObjectRef products = + createPBXGroup("Documentation", sourceTree, productsList); + objects.put(products.getID(), products.getProperties()); + return products; + } + + /** + * Add file reference of product to map of objects. + * @param objects object map. + * @param linkTarget build description for executable or shared library. + * @return file reference to generated executable or shared library. + */ + private PBXObjectRef addProduct(final Map objects, + final TargetInfo linkTarget) { + + // + // create file reference for executable file + // forget Ant's location, just place in XCode's default location + PBXObjectRef executable = createPBXFileReference("BUILD_PRODUCTS_DIR", + linkTarget.getOutput().getParent(), + linkTarget.getOutput()); + Map executableProperties = executable.getProperties(); + + String fileType = getFileType(linkTarget); + executableProperties.put("explicitFileType", fileType); + executableProperties.put("includeInIndex", "0"); + objects.put(executable.getID(), executableProperties); + + return executable; + } + + + /** + * Add file references for all source files to map of objects. + * @param objects map of objects. + * @param sourceTree source tree. + * @param basePath parent of XCode project dir + * @param targets build targets. + * @return list containing file references of source files. + */ + private List addSources(final Map objects, + final String sourceTree, + final String basePath, + final Hashtable targets) { + List sourceGroupChildren = new ArrayList(); + + ArrayList sourceList = new ArrayList(targets.size()); + Iterator targetIter = targets.values().iterator(); + while (targetIter.hasNext()) { + TargetInfo info = (TargetInfo) targetIter.next(); + File[] targetsources = info.getSources(); + for (int i = 0; i < targetsources.length; i++) { + sourceList.add(targetsources[i]); + } + } + Object[] sortedSources = sourceList.toArray(); + Arrays.sort(sortedSources, new Comparator() { + public int compare(final Object o1, final Object o2) { + return (((File) o1).getName().compareTo( + ((File) o2).getName())); + } + }); + for (int i = 0; i < sortedSources.length; i++) { + PBXObjectRef fileRef = createPBXFileReference(sourceTree, + basePath, (File) sortedSources[i]); + sourceGroupChildren.add(fileRef); + objects.put(fileRef.getID(), fileRef.getProperties()); + } + + return sourceGroupChildren; + } + + /** + * Add native target configuration list. + * @param objects map of objects. + * @param projectName project name. + * @return build configurations for native target. + */ + private PBXObjectRef addNativeTargetConfigurationList(final Map objects, + final String projectName) { + + // + // Create a configuration list with + // two stock configurations: Debug and Release + // + List configurations = new ArrayList(); + Map debugSettings = new HashMap(); + debugSettings.put("COPY_PHASE_STRIP", "NO"); + debugSettings.put("GCC_DYNAMIC_NO_PIC", "NO"); + debugSettings.put("GCC_ENABLE_FIX_AND_CONTINUE", "YES"); + debugSettings.put("GCC_MODEL_TUNING", "G5"); + debugSettings.put("GCC_OPTIMIZATION_LEVEL", "0"); + debugSettings.put("INSTALL_PATH", "$(HOME)/bin"); + debugSettings.put("PRODUCT_NAME", projectName); + debugSettings.put("ZERO_LINK", "YES"); + PBXObjectRef debugConfig = createXCBuildConfiguration("Debug", + debugSettings); + objects.put(debugConfig.getID(), debugConfig.getProperties()); + configurations.add(debugConfig); + + Map releaseSettings = new HashMap(); + List archs = new ArrayList(); + archs.add("ppc"); + archs.add("i386"); + releaseSettings.put("ARCHS", archs); + releaseSettings.put("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO"); + releaseSettings.put("GCC_MODEL_TUNING", "G5"); + releaseSettings.put("INSTALL_PATH", "$(HOME)/bin"); + releaseSettings.put("PRODUCT_NAME", projectName); + PBXObjectRef releaseConfig = createXCBuildConfiguration("Release", + releaseSettings); + objects.put(releaseConfig.getID(), releaseConfig.getProperties()); + configurations.add(releaseConfig); + + PBXObjectRef configurationList = createXCConfigurationList(configurations); + objects.put(configurationList.getID(), configurationList.getProperties()); + return configurationList; + } + + + + /** + * Add project configuration list. + * @param objects map of objects. + * @param baseDir base directory. + * @param compilerConfig compiler configuration. + * @return project configuration object. + */ + private PBXObjectRef addProjectConfigurationList(final Map objects, + final String baseDir, + final List dependencies, + final CommandLineCompilerConfiguration compilerConfig, + final CommandLineLinkerConfiguration linkerConfig) { + // + // Create a configuration list with + // two stock configurations: Debug and Release + // + List configurations = new ArrayList(); + Map debugSettings = new HashMap(); + debugSettings.put("GCC_WARN_ABOUT_RETURN_TYPE", "YES"); + debugSettings.put("GCC_WARN_UNUSED_VARIABLE", "YES"); + debugSettings.put("PREBINDING", "NO"); + debugSettings.put("SDKROOT", "/Developer/SDKs/MacOSX10.4u.sdk"); + + + PBXObjectRef debugConfig = createXCBuildConfiguration("Debug", debugSettings); + objects.put(debugConfig.getID(), debugConfig.getProperties()); + configurations.add(debugConfig); + + Map releaseSettings = new HashMap(); + releaseSettings.put("GCC_WARN_ABOUT_RETURN_TYPE", "YES"); + releaseSettings.put("GCC_WARN_UNUSED_VARIABLE", "YES"); + releaseSettings.put("PREBINDING", "NO"); + releaseSettings.put("SDKROOT", "/Developer/SDKs/MacOSX10.4u.sdk"); + PBXObjectRef releaseConfig = + createXCBuildConfiguration("Release", releaseSettings); + objects.put(releaseConfig.getID(), releaseConfig.getProperties()); + configurations.add(releaseConfig); + PBXObjectRef configurationList = createXCConfigurationList(configurations); + Map projectConfigurationListProperties = configurationList.getProperties(); + projectConfigurationListProperties.put("defaultConfigurationIsVisible", "0"); + projectConfigurationListProperties.put("defaultConfigurationName", "Debug"); + objects.put(configurationList.getID(), configurationList.getProperties()); + + // + // add include paths to both configurations + // + File[] includeDirs = compilerConfig.getIncludePath(); + if (includeDirs.length > 0) { + ArrayList includePaths = new ArrayList(); + Map includePathMap = new HashMap(); + for (int i = 0; i < includeDirs.length; i++) { + if(!CUtil.isSystemPath(includeDirs[i])) { + String absPath = includeDirs[i].getAbsolutePath(); + if (!includePathMap.containsKey(absPath)) { + if(absPath.startsWith("/usr/")) { + includePaths.add(CUtil.toUnixPath(absPath)); + } else { + String relPath = CUtil.toUnixPath( + CUtil.getRelativePath(baseDir, includeDirs[i])); + includePaths.add(relPath); + } + includePathMap.put(absPath, absPath); + } + } + } + includePaths.add("${inherited)"); + debugSettings.put("HEADER_SEARCH_PATHS", includePaths); + releaseSettings.put("HEADER_SEARCH_PATHS", includePaths); + } + + // + // add preprocessor definitions to both configurations + // + // + String[] preArgs = compilerConfig.getPreArguments(); + List defines = new ArrayList(); + for (int i = 0; i < preArgs.length; i++) { + if (preArgs[i].startsWith("-D")) { + defines.add(preArgs[i].substring(2)); + } + } + if (defines.size() > 0) { + defines.add("$(inherited)"); + debugSettings.put("GCC_PREPROCESSOR_DEFINITIONS", defines); + releaseSettings.put("GCC_PREPROCESSOR_DEFINITIONS", defines); + } + + + if (linkerConfig != null) { + Map librarySearchMap = new HashMap(); + List librarySearchPaths = new ArrayList(); + List otherLdFlags = new ArrayList(); + String[] linkerArgs = linkerConfig.getEndArguments(); + for (int i = 0; i < linkerArgs.length; i++) { + if (linkerArgs[i].startsWith("-L")) { + String libDir = linkerArgs[i].substring(2); + if (!librarySearchMap.containsKey(libDir)) { + if (!libDir.equals("/usr/lib")) { + librarySearchPaths.add( + CUtil.toUnixPath(CUtil.getRelativePath(baseDir, + new File(libDir)))); + } + librarySearchMap.put(libDir, libDir); + + } + } else if (linkerArgs[i].startsWith("-l")) { + // + // check if library is in dependencies list + // + String libName = linkerArgs[i].substring(2); + boolean found = false; + for(Iterator iter = dependencies.iterator();iter.hasNext();) { + DependencyDef dependency = (DependencyDef) iter.next(); + if (libName.startsWith(dependency.getName())) { + File dependencyFile = dependency.getFile(); + if (dependencyFile != null && + new File(dependencyFile.getAbsolutePath() + ".xcodeproj").exists()) { + found = true; + break; + } + } + } + if (!found) { + otherLdFlags.add(linkerArgs[i]); + } + } + } + + + debugSettings.put("LIBRARY_SEARCH_PATHS", librarySearchPaths); + debugSettings.put("OTHER_LDFLAGS", otherLdFlags); + releaseSettings.put("LIBRARY_SEARCH_PATHS", librarySearchPaths); + releaseSettings.put("OTHER_LDFLAGS", otherLdFlags); + } + return configurationList; + } + + /** + * Add native target to map of objects. + * @param objects map of objects. + * @param linkTarget description of executable or shared library. + * @param product product. + * @param projectName project name. + * @param sourceGroupChildren source files needed to build product. + * @return native target. + */ + private PBXObjectRef addNativeTarget(final Map objects, + final TargetInfo linkTarget, + final PBXObjectRef product, + final String projectName, + final List sourceGroupChildren, + final List frameworkBuildFiles) { + + PBXObjectRef buildConfigurations = + addNativeTargetConfigurationList(objects, projectName); + + int buildActionMask = 2147483647; + List buildPhases = new ArrayList(); + + Map settings = new HashMap(); + settings.put("ATTRIBUTES", new ArrayList()); + List buildFiles = new ArrayList(); + for (Iterator iter = sourceGroupChildren.iterator(); + iter.hasNext();) { + PBXObjectRef sourceFile = (PBXObjectRef) iter.next(); + PBXObjectRef buildFile = createPBXBuildFile(sourceFile, settings); + buildFiles.add(buildFile); + objects.put(buildFile.getID(), buildFile.getProperties()); + } + + + PBXObjectRef sourcesBuildPhase = createPBXSourcesBuildPhase(buildActionMask, + buildFiles, false); + objects.put(sourcesBuildPhase.getID(), sourcesBuildPhase.getProperties()); + buildPhases.add(sourcesBuildPhase); + + + buildActionMask = 8; + PBXObjectRef frameworksBuildPhase = + createPBXFrameworksBuildPhase(buildActionMask, + frameworkBuildFiles, false); + objects.put(frameworksBuildPhase.getID(), frameworksBuildPhase.getProperties()); + buildPhases.add(frameworksBuildPhase); + + PBXObjectRef copyFilesBuildPhase = createPBXCopyFilesBuildPhase(8, + "/usr/share/man/man1", "0", new ArrayList(), true); + objects.put(copyFilesBuildPhase.getID(), copyFilesBuildPhase.getProperties()); + buildPhases.add(copyFilesBuildPhase); + + List buildRules = new ArrayList(); + + List dependencies = new ArrayList(); + + String productInstallPath = "$(HOME)/bin"; + + String productType = getProductType(linkTarget); + + PBXObjectRef nativeTarget = createPBXNativeTarget(projectName, + buildConfigurations, buildPhases, buildRules, dependencies, + productInstallPath, projectName, product, productType); + objects.put(nativeTarget.getID(), nativeTarget.getProperties()); + + return nativeTarget; + } + + private int getProductTypeIndex(final TargetInfo linkTarget) { + String outPath = linkTarget.getOutput().getPath(); + String outExtension = null; + int lastDot = outPath.lastIndexOf('.'); + if (lastDot != -1) { + outExtension = outPath.substring(lastDot); + } + if (".a".equalsIgnoreCase(outExtension) || ".lib".equalsIgnoreCase(outExtension)) { + return 1; + } else if (".dylib".equalsIgnoreCase(outExtension) || + ".so".equalsIgnoreCase(outExtension) || + ".dll".equalsIgnoreCase(outExtension)) { + return 2; + } + return 0; + } + + private String getProductType(final TargetInfo linkTarget) { + switch(getProductTypeIndex(linkTarget)) { + case 1: + return "com.apple.product-type.library.static"; + case 2: + return "com.apple.product-type.library.dynamic"; + default: + return "com.apple.product-type.tool"; + } + } + + private String getFileType(final TargetInfo linkTarget) { + switch(getProductTypeIndex(linkTarget)) { + case 1: + return "archive.ar"; + case 2: + return "compiled.mach-o.dylib"; + default: + return "compiled.mach-o.executable"; + } + } + + + /** + * Create PBXFileReference. + * @param sourceTree source tree. + * @param baseDir base directory. + * @param file file. + * @return PBXFileReference object. + */ + private static PBXObjectRef createPBXFileReference(final String sourceTree, + final String baseDir, + final File file) { + Map map = new HashMap(); + map.put("isa", "PBXFileReference"); + + String relPath = CUtil.toUnixPath(CUtil.getRelativePath(baseDir, file)); + map.put("path", relPath); + map.put("name", file.getName()); + map.put("sourceTree", sourceTree); + return new PBXObjectRef(map); + } + + /** + * Create PBXGroup. + * @param name group name. + * @param sourceTree source tree. + * @param children list of PBXFileReferences. + * @return group. + */ + private static PBXObjectRef createPBXGroup(final String name, + final String sourceTree, + final List children) { + Map map = new HashMap(); + map.put("isa", "PBXGroup"); + map.put("name", name); + map.put("sourceTree", sourceTree); + map.put("children", children); + return new PBXObjectRef(map); + } + + /** + * Create PBXProject. + * @param buildConfigurationList build configuration list. + * @param mainGroup main group. + * @param projectDirPath project directory path. + * @param targets targets. + * @param projectRoot projectRoot directory relative to + * @return project. + */ + private static PBXObjectRef createPBXProject(final PBXObjectRef buildConfigurationList, + final PBXObjectRef mainGroup, + final String projectDirPath, + final String projectRoot, + final List targets) { + Map map = new HashMap(); + map.put("isa", "PBXProject"); + map.put("buildConfigurationList", buildConfigurationList.getID()); + map.put("hasScannedForEncodings", "0"); + map.put("mainGroup", mainGroup.getID()); + map.put("projectDirPath", projectDirPath); + map.put("targets", targets); + map.put("projectRoot", projectRoot); + return new PBXObjectRef(map); + } + + /** + * Create XCConfigurationList. + * @param buildConfigurations build configurations. + * @return configuration list. + */ + private static PBXObjectRef createXCConfigurationList(final List buildConfigurations) { + Map map = new HashMap(); + map.put("isa", "XCConfigurationList"); + map.put("buildConfigurations", buildConfigurations); + return new PBXObjectRef(map); + } + + + /** + * Create XCBuildConfiguration. + * @param name name. + * @param buildSettings build settings. + * @return build configuration. + */ + private static PBXObjectRef createXCBuildConfiguration(final String name, + final Map buildSettings) { + Map map = new HashMap(); + map.put("isa", "XCBuildConfiguration"); + map.put("buildSettings", buildSettings); + map.put("name", name); + return new PBXObjectRef(map); + } + + /** + * Create PBXNativeTarget. + * @param name name. + * @param buildConfigurationList build configuration list. + * @param buildPhases build phases. + * @param buildRules build rules. + * @param dependencies dependencies. + * @param productInstallPath product install path. + * @param productName product name. + * @param productReference file reference for product. + * @param productType product type. + * @return native target. + */ + private static PBXObjectRef createPBXNativeTarget(final String name, + final PBXObjectRef buildConfigurationList, + final List buildPhases, + final List buildRules, + final List dependencies, + final String productInstallPath, + final String productName, + final PBXObjectRef productReference, + final String productType) { + Map map = new HashMap(); + map.put("isa", "PBXNativeTarget"); + map.put("buildConfigurationList", buildConfigurationList); + map.put("buildPhases", buildPhases); + map.put("buildRules", buildRules); + map.put("dependencies", dependencies); + map.put("name", name); + map.put("productInstallPath", productInstallPath); + map.put("productName", productName); + map.put("productReference", productReference); + map.put("productType", productType); + return new PBXObjectRef(map); + } + + /** + * Create PBXSourcesBuildPhase. + * @param buildActionMask build action mask. + * @param files source files. + * @param runOnly if true, phase should only be run on deployment. + * @return PBXSourcesBuildPhase. + */ + private static PBXObjectRef createPBXSourcesBuildPhase(int buildActionMask, + List files, + boolean runOnly) { + Map map = new HashMap(); + map.put("buildActionMask", + String.valueOf(buildActionMask)); + map.put("files", files); + map.put("isa", "PBXSourcesBuildPhase"); + map.put("runOnlyForDeploymentPostprocessing", toString(runOnly)); + return new PBXObjectRef(map); + } + + /** + * Create PBXBuildFile. + * @param fileRef source file. + * @param settings build settings. + * @return PBXBuildFile. + */ + private static PBXObjectRef createPBXBuildFile(PBXObjectRef fileRef, + Map settings) { + Map map = new HashMap(); + map.put("fileRef", fileRef); + map.put("isa", "PBXBuildFile"); + if (settings != null) { + map.put("settings", settings); + } + return new PBXObjectRef(map); + } + + /** + * Create PBXFrameworksBuildPhase. + * @param buildActionMask build action mask. + * @param files files. + * @param runOnly if true, phase should only be run on deployment. + * @return PBXFrameworkBuildPhase. + */ + private static PBXObjectRef createPBXFrameworksBuildPhase( + final int buildActionMask, + final List files, + final boolean runOnly) { + Map map = new HashMap(); + map.put("isa", "PBXFrameworksBuildPhase"); + map.put("buildActionMask", NumberFormat.getIntegerInstance(Locale.US).format(buildActionMask)); + map.put("files", files); + map.put("runOnlyForDeploymentPostprocessing", toString(runOnly)); + return new PBXObjectRef(map); + } + + /** + * Create a build phase that copies files to a destination. + * @param buildActionMask build action mask. + * @param dstPath destination path. + * @param dstSubfolderSpec subfolder spec. + * @param files files. + * @param runOnly if true, phase should only be run on deployment. + * @return PBXCopyFileBuildPhase. + */ + private static PBXObjectRef createPBXCopyFilesBuildPhase( + final int buildActionMask, + final String dstPath, + final String dstSubfolderSpec, + final List files, + final boolean runOnly) { + Map map = new HashMap(); + map.put("isa", "PBXCopyFilesBuildPhase"); + map.put("buildActionMask", NumberFormat.getIntegerInstance(Locale.US).format(buildActionMask)); + map.put("dstPath", dstPath); + map.put("dstSubfolderSpec", dstSubfolderSpec); + map.put("files", files); + map.put("runOnlyForDeploymentPostprocessing", toString(runOnly)); + return new PBXObjectRef(map); + } + + + /** + * Create a proxy for a file in a different project. + * @param containerPortal XcodeProject containing file. + * @param proxyType proxy type. + * @return PBXContainerItemProxy. + */ + private static PBXObjectRef createPBXContainerItemProxy( + final PBXObjectRef containerPortal, + final int proxyType, + final String remoteInfo) { + Map map = new HashMap(); + map.put("isa", "PBXContainerItemProxy"); + map.put("containerPortal", containerPortal); + map.put("proxyType", NumberFormat.getIntegerInstance(Locale.US).format(proxyType)); + map.put("remoteInfo", remoteInfo); + return new PBXObjectRef(map); + } + + + /** + * Create a proxy for a file in a different project. + * @param remoteRef PBXContainerItemProxy for reference. + * @param dependency dependency. + * @return PBXContainerItemProxy. + */ + private static PBXObjectRef createPBXReferenceProxy( + final PBXObjectRef remoteRef, + final DependencyDef dependency) { + Map map = new HashMap(); + map.put("isa", "PBXReferenceProxy"); + String fileType = "compiled.mach-o.dylib"; + map.put("fileType", fileType); + map.put("remoteRef", remoteRef); + map.put("path", dependency.getFile().getName() + ".dylib"); + map.put("sourceTree", "BUILT_PRODUCTS_DIR"); + return new PBXObjectRef(map); + } + + /** + * Method returns "1" for true, "0" for false. + * @param b boolean value. + * @return "1" for true, "0" for false. + */ + private static String toString(boolean b) { + if (b) { + return "1"; + } else { + return "0"; + } + } + + /** + * Represents a property map with an 96 bit identity. + * When placed in a property list, this object will + * output the string representation of the identity + * which XCode uses to find the corresponding property + * bag in the "objects" property of the top-level property list. + */ + private static final class PBXObjectRef { + /** + * Identifier. + */ + private final String id; + /** + * Properties. + */ + private final Map properties; + /** + * Next available identifier. + */ + private static int nextID = 0; + + /** + * Create reference. + * @param props properties. + */ + public PBXObjectRef(final Map props) { + if (props == null) { + throw new NullPointerException("props"); + } + StringBuffer buf = new StringBuffer("000000000000000000000000"); + String idStr = Integer.toHexString(nextID++); + buf.replace(buf.length() - idStr.length(), buf.length(), idStr); + id = buf.toString(); + properties = props; + } + + /** + * Get object identifier. + * @return identifier. + */ + public String toString() { + return id; + } + + /** + * Get object identifier. + * @return object identifier. + */ + public String getID() { + return id; + } + + /** + * Get properties. + * @return properties. + */ + public Map getProperties() { + return properties; + } + } + + /** + * Gets the first recognized compiler from the + * compilation targets. + * + * @param targets compilation targets + * @return representative (hopefully) compiler configuration + */ + private CommandLineCompilerConfiguration + getBaseCompilerConfiguration(Hashtable targets) { + // + // find first target with an GNU C++ compilation + // + CommandLineCompilerConfiguration compilerConfig; + // + // get the first target and assume that it is representative + // + Iterator targetIter = targets.values().iterator(); + while (targetIter.hasNext()) { + TargetInfo targetInfo = (TargetInfo) targetIter.next(); + ProcessorConfiguration config = targetInfo.getConfiguration(); + // + // for the first cl compiler + // + if (config instanceof CommandLineCompilerConfiguration) { + compilerConfig = (CommandLineCompilerConfiguration) config; + if (compilerConfig.getCompiler() instanceof GccCCompiler) { + return compilerConfig; + } + } + } + return null; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/package.html b/src/main/java/net/sf/antcontrib/cpptasks/apple/package.html new file mode 100644 index 0000000..43a2ac3 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/package.html @@ -0,0 +1,27 @@ + + + + + + + +Project writer for Apple Xcode + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java new file mode 100644 index 0000000..11004ad --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java @@ -0,0 +1,210 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.arm; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.OptimizationEnum; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the ARM C Compilers + * + * See Doc No: ARM DUI 0151A, Issued: Nov 2001 at + * http://www.arm.com/arm/User_Guides?OpenDocument + * + * @author Curt Arnold + * + */ +public class ADSCCompiler extends CommandLineCCompiler { + /** + * Header file extensions + */ + private static final String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + /** + * Source file extensions + */ + private static final String[] sourceExtensions = new String[]{".c", ".cc", + ".cpp", ".cxx", ".c++"}; + /** + * Singleton for ARM 32-bit C compiler + */ + private static final ADSCCompiler armcc = new ADSCCompiler("armcc", false, + null); + /** + * Singleton for ARM 32-bit C++ compiler + */ + private static final ADSCCompiler armcpp = new ADSCCompiler("armcpp", + false, null); + /** + * Singleton for ARM 16-bit C compiler + */ + private static final ADSCCompiler tcc = new ADSCCompiler("tcc", false, null); + /** + * Singleton for ARM 16-bit C++ compiler + */ + private static final ADSCCompiler tcpp = new ADSCCompiler("tcpp", false, + null); + /** + * Singleton for ARM 32-bit C compiler + */ + public static ADSCCompiler getArmCC() { + return armcc; + } + /** + * Singleton for ARM 32-bit C++ compiler + */ + public static ADSCCompiler getArmCpp() { + return armcpp; + } + /** + * Singleton for ARM 16-bit C compiler + */ + public static ADSCCompiler getThumbCC() { + return tcc; + } + /** + * Singleton for ARM 16-bit C++ compiler + */ + public static ADSCCompiler getThumbCpp() { + return tcpp; + } + private static void quoteFile(StringBuffer buf, String outPath) { + if (outPath.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + } + /** + * Private constructor + * + * @param command + * executable name + * @param newEnvironment + * Change environment + * @param env + * New environment + */ + private ADSCCompiler(String command, boolean newEnvironment, Environment env) { + super(command, "-vsn", sourceExtensions, headerExtensions, ".o", false, + null, newEnvironment, env); + } + /** + * {@inheritDoc} + */ + protected void addImpliedArgs(Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + if (debug) { + args.addElement("-g"); + } + // + // didn't see anything about producing + // anything other than executables in the docs + if (linkType.isExecutable()) { + } else if (linkType.isSharedLibrary()) { + } + } + /** + * Adds flags that customize the warnings reported + * + * Compiler does not appear to have warning levels but ability to turn off + * specific errors by explicit switches, could fabricate levels by + * prioritizing errors. + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addWarningSwitch(java.util.Vector, + * int) + */ + protected void addWarningSwitch(Vector args, int warnings) { + } + /** + * Add command line options for preprocessor macro + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getDefineSwitch(java.lang.StringBuffer, + * java.lang.String, java.lang.String) + */ + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("-D"); + buffer.append(define); + if (value != null) { + buffer.append('='); + buffer.append(value); + } + } + /** + * ARMINC environment variable contains the default include path + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getEnvironmentIncludePath() + */ + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("ARMINC", ";"); + } + /** + * Returns command line option to specify include directory + * + */ + protected String getIncludeDirSwitch(String source) { + StringBuffer buf = new StringBuffer("-I"); + quoteFile(buf, source); + return buf.toString(); + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return ADSLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return ADSLinker.getDllInstance(); + } + return ADSLinker.getInstance(); + } + /** + * Maximum command line length + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getMaximumCommandLength() + */ + public int getMaximumCommandLength() { + return 1000; + } + /* + * Adds command to undefine preprocessor macro + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getUndefineSwitch(java.lang.StringBuffer, + * java.lang.String) + */ + protected void getUndefineSwitch(StringBuffer buffer, String define) { + buffer.append("-U"); + buffer.append(define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java new file mode 100644 index 0000000..65c430f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java @@ -0,0 +1,159 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.arm; + +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for ARM Librarian + * + * @author Curt Arnold + */ +public class ADSLibrarian extends CommandLineLinker { + + private static final ADSLibrarian instance = new ADSLibrarian(); + + public static ADSLibrarian getInstance() { + return instance; + } + + private ADSLibrarian() + { + super("armar",null, + new String[] { ".o" }, new String[0], ".lib", false, null); + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long, java.util.Vector) + */ + protected void addBase(long base, Vector args) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean, java.util.Vector) + */ + protected void addFixed(Boolean fixed, Vector args) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean, net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector) + */ + protected void addImpliedArgs( + boolean debug, + LinkType linkType, + Vector args) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean, java.util.Vector) + */ + protected void addIncremental(boolean incremental, Vector args) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean, java.util.Vector) + */ + protected void addMap(boolean map, Vector args) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int, java.util.Vector) + */ + protected void addStack(int stack, Vector args) { + // TODO Auto-generated method stub + + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String) + */ + protected String getCommandFileSwitch(String commandFile) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath() + */ + public File[] getLibraryPath() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[]) + */ + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return new String[0]; + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + public Linker getLinker(LinkType linkType) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength() + */ + protected int getMaximumCommandLength() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String) + */ + protected String[] getOutputFileSwitch(String outputFile) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive() + */ + public boolean isCaseSensitive() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java new file mode 100644 index 0000000..fda52fa --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/arm/ADSLinker.java @@ -0,0 +1,166 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.arm; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for the ARM Linker + * + * @author CurtA + */ +public class ADSLinker extends CommandLineLinker { + private static final ADSLinker dllInstance = new ADSLinker(".o"); + private static final ADSLinker instance = new ADSLinker(".axf"); + public static ADSLinker getDllInstance() { + return dllInstance; + } + public static ADSLinker getInstance() { + return instance; + } + private ADSLinker(String outputSuffix) { + super("armlink", "-vsn", new String[]{".o", ".lib", ".res"}, + new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null); + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long, + * java.util.Vector) + */ + protected void addBase(long base, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean, + * java.util.Vector) + */ + protected void addFixed(Boolean fixed, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean, + * net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector) + */ + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (debug) { + args.addElement("-debug"); + } + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean, + * java.util.Vector) + */ + protected void addIncremental(boolean incremental, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean, + * java.util.Vector) + */ + protected void addMap(boolean map, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int, + * java.util.Vector) + */ + protected void addStack(int stack, Vector args) { + // TODO Auto-generated method stub + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + // TODO Auto-generated method stub + + } + + /** + * May have to make this String array return + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String) + */ + protected String getCommandFileSwitch(String commandFile) { + return "-via" + commandFile; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath() + */ + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("ARMLIB", ";"); + } + /* + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[]) + */ + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + // + // TODO: looks like bad extension + // + return new String[]{".o"}; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + public Linker getLinker(LinkType linkType) { + return this; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength() + */ + protected int getMaximumCommandLength() { + return 1024; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String) + */ + protected String[] getOutputFileSwitch(String outputFile) { + return new String[]{"-output", outputFile}; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive() + */ + public boolean isCaseSensitive() { + return false; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java new file mode 100644 index 0000000..fd9c657 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java @@ -0,0 +1,134 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.PrecompilingCommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Borland(r) C/C++ compiler. + * + * @author Curt Arnold + */ +public class BorlandCCompiler extends PrecompilingCommandLineCCompiler { + private static final String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private static final String[] sourceExtensions = new String[]{".c", ".cc", + ".cpp", ".cxx", ".c++"}; + private static final BorlandCCompiler instance = new BorlandCCompiler( + false, null); + public static BorlandCCompiler getInstance() { + return instance; + } + private BorlandCCompiler(boolean newEnvironment, Environment env) { + super("bcc32", "--version", sourceExtensions, headerExtensions, ".obj", false, + null, newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("-c"); + // + // turn off compiler autodependency since + // we do it ourselves + args.addElement("-X"); + if (exceptions) { + args.addElement("-x"); + } else { + args.addElement("-x-"); + } + if (multithreaded) { + args.addElement("-tWM"); + } + if (debug) { + args.addElement("-Od"); + args.addElement("-v"); + } else { + if (optimization != null) { + if (optimization.isSpeed()) { + args.addElement("-O1"); + } else { + if (optimization.isSpeed()) { + args.addElement("-O2"); + } else { + if (optimization.isNoOptimization()) { + args.addElement("-Od"); + } + } + } + } + } + if (rtti != null && !rtti.booleanValue()) { + args.addElement("-RT-"); + } + } + protected void addWarningSwitch(Vector args, int level) { + BorlandProcessor.addWarningSwitch(args, level); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new BorlandCCompiler(newEnvironment, env); + } + return this; + } + protected CompilerConfiguration createPrecompileGeneratingConfig( + CommandLineCompilerConfiguration baseConfig, File prototype, + String lastInclude) { + String[] additionalArgs = new String[]{"-H=" + lastInclude, "-Hc"}; + return new CommandLineCompilerConfiguration(baseConfig, additionalArgs, + null, true); + } + protected CompilerConfiguration createPrecompileUsingConfig( + CommandLineCompilerConfiguration baseConfig, File prototype, + String lastInclude, String[] exceptFiles) { + String[] additionalArgs = new String[]{"-Hu"}; + return new CommandLineCompilerConfiguration(baseConfig, additionalArgs, + exceptFiles, false); + } + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + BorlandProcessor.getDefineSwitch(buffer, define, value); + } + protected File[] getEnvironmentIncludePath() { + return BorlandProcessor.getEnvironmentPath("bcc32", 'I', + new String[]{"..\\include"}); + } + protected String getIncludeDirSwitch(String includeDir) { + return BorlandProcessor.getIncludeDirSwitch("-I", includeDir); + } + public Linker getLinker(LinkType type) { + return BorlandLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 1024; + } + protected void getUndefineSwitch(StringBuffer buffer, String define) { + BorlandProcessor.getUndefineSwitch(buffer, define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java new file mode 100644 index 0000000..a452b1b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java @@ -0,0 +1,70 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.parser.AbstractParser; +import net.sf.antcontrib.cpptasks.parser.AbstractParserState; +import net.sf.antcontrib.cpptasks.parser.LetterState; +import net.sf.antcontrib.cpptasks.parser.WhitespaceOrLetterState; +/** + * A parser that paths from a borland cfg file + * + * @author Curt Arnold + */ +public final class BorlandCfgParser extends AbstractParser { + private AbstractParserState newLineState; + private final Vector path = new Vector(); + /** + * + * + */ + public BorlandCfgParser(char switchChar) { + // + // a quoted path (-I"some path") + // doesn't end till a close quote and will be abandoned + // if a new line is encountered first + // + AbstractParserState quote = new CfgFilenameState(this, new char[]{'"'}); + // + // an unquoted path (-Ic:\borland\include) + // ends at the first space or new line + AbstractParserState unquote = new CfgFilenameState(this, new char[]{ + ' ', '\n', '\r'}); + AbstractParserState quoteBranch = new QuoteBranchState(this, quote, + unquote); + AbstractParserState toNextSwitch = new ConsumeToSpaceOrNewLine(this); + AbstractParserState switchState = new LetterState(this, switchChar, + quoteBranch, toNextSwitch); + newLineState = new WhitespaceOrLetterState(this, '-', switchState); + } + public void addFilename(String include) { + path.addElement(include); + } + public AbstractParserState getNewLineState() { + return newLineState; + } + public String[] parsePath(Reader reader) throws IOException { + path.setSize(0); + super.parse(reader); + String[] retval = new String[path.size()]; + path.copyInto(retval); + return retval; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java new file mode 100644 index 0000000..703ddd3 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java @@ -0,0 +1,219 @@ +/* + * + * Copyright 2002-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import java.io.File; +import java.io.IOException; +import java.util.Vector; +import org.apache.tools.ant.BuildException; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for the Borland(r) tlib Librarian + * + * @author Curt Arnold + */ +public class BorlandLibrarian extends CommandLineLinker { + private static final BorlandLibrarian instance = new BorlandLibrarian(); + public static BorlandLibrarian getInstance() { + return instance; + } + private BorlandLibrarian() { + super("tlib", "--version", new String[]{".obj"}, new String[0], ".lib", false, + null); + } + protected void addBase(long base, Vector args) { + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + } + protected void addIncremental(boolean incremental, Vector args) { + } + protected void addMap(boolean map, Vector args) { + } + protected void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + protected String getCommandFileSwitch(String cmdFile) { + // + // tlib requires quotes around paths containing - + // ilink32 doesn't like them + StringBuffer buf = new StringBuffer("@"); + BorlandProcessor.quoteFile(buf, cmdFile); + return buf.toString(); + } + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return BorlandProcessor.getLibraryPatterns(libnames, libType); + } + public Linker getLinker(LinkType type) { + return BorlandLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 1024; + } + public String[] getOutputFileSwitch(String outFile) { + return BorlandProcessor.getOutputFileSwitch(outFile); + } + public boolean isCaseSensitive() { + return BorlandProcessor.isCaseSensitive(); + } + /** + * Gets identifier for the linker. + * + * TLIB will lockup when attempting to get version + * information. Since the Librarian version isn't critical + * just return a stock response. + */ + public String getIdentifier() { + return "TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation"; + } + + /** + * Prepares argument list for exec command. + * + * @param outputDir linker output directory + * @param outputName linker output name + * @param sourceFiles + * linker input files (.obj, .o, .res) + * @param config + * linker configuration + * @return arguments for runTask + */ + protected String[] prepareArguments( + CCTask task, + String outputDir, + String outputName, + String[] sourceFiles, + CommandLineLinkerConfiguration config) { + String[] preargs = config.getPreArguments(); + String[] endargs = config.getEndArguments(); + StringBuffer buf = new StringBuffer(); + Vector execArgs = new Vector(preargs.length + endargs.length + 10 + + sourceFiles.length); + + execArgs.addElement(this.getCommand()); + String outputFileName = new File(outputDir, outputName).toString(); + execArgs.addElement(quoteFilename(buf, outputFileName)); + + for (int i = 0; i < preargs.length; i++) { + execArgs.addElement(preargs[i]); + } + + // + // add a place-holder for page size + // + int pageSizeIndex = execArgs.size(); + execArgs.addElement(null); + + int objBytes = 0; + + for (int i = 0; i < sourceFiles.length; i++) { + String last4 = sourceFiles[i] + .substring(sourceFiles[i].length() - 4).toLowerCase(); + if (last4.equals(".def")) { + } else { + if (last4.equals(".res")) { + } else { + if (last4.equals(".lib")) { + } else { + execArgs.addElement("+" + quoteFilename(buf, sourceFiles[i])); + objBytes += new File(sourceFiles[i]).length(); + } + } + } + } + + for (int i = 0; i < endargs.length; i++) { + execArgs.addElement(endargs[i]); + } + + String[] execArguments = new String[execArgs.size()]; + execArgs.copyInto(execArguments); + + int minPageSize = objBytes >> 16; + int pageSize = 0; + for(int i = 4; i <= 15; i++) { + pageSize = 1 << i; + if (pageSize > minPageSize) break; + } + execArguments[pageSizeIndex] = "/P" + Integer.toString(pageSize); + + return execArguments; + } + + /** + * Prepares argument list to execute the linker using a response file. + * + * @param outputFile + * linker output file + * @param args + * output of prepareArguments + * @return arguments for runTask + */ + protected String[] prepareResponseFile(File outputFile, String[] args) + throws IOException { + String[] cmdargs = BorlandProcessor.prepareResponseFile(outputFile, args, " & \n"); + cmdargs[cmdargs.length - 1] = getCommandFileSwitch(cmdargs[cmdargs.length -1]); + return cmdargs; + } + + /** + * Builds a library + * + */ + public void link(CCTask task, + File outputFile, + String[] sourceFiles, + CommandLineLinkerConfiguration config) + throws BuildException + { + // + // delete any existing library + outputFile.delete(); + // + // build a new library + super.link(task, outputFile, sourceFiles, config); + } + + /** + * Encloses problematic file names within quotes. + * @param buf string buffer + * @param filename source file name + * @return filename potentially enclosed in quotes. + */ + protected String quoteFilename(StringBuffer buf,String filename) { + buf.setLength(0); + BorlandProcessor.quoteFile(buf, filename); + return buf.toString(); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java new file mode 100644 index 0000000..6a28805 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java @@ -0,0 +1,293 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.platforms.WindowsPlatform; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for the Borland(r) ilink32 linker + * + * @author Curt Arnold + */ +public final class BorlandLinker extends CommandLineLinker { + private static final BorlandLinker dllLinker = new BorlandLinker(".dll"); + private static final BorlandLinker instance = new BorlandLinker(".exe"); + public static BorlandLinker getInstance() { + return instance; + } + private BorlandLinker(String outputSuffix) { + super("ilink32", "-r", new String[]{".obj", ".lib", ".res"}, + new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null); + } + protected void addBase(long base, Vector args) { + if (base >= 0) { + String baseAddr = Long.toHexString(base); + args.addElement("-b:" + baseAddr); + } + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (linkType.isExecutable()) { + if (linkType.isSubsystemConsole()) { + args.addElement("/ap"); + } else { + if (linkType.isSubsystemGUI()) { + args.addElement("/Tpe"); + } + } + } + if (linkType.isSharedLibrary()) { + args.addElement("/Tpd"); + args.addElement("/Gi"); + } + if (debug) { + args.addElement("-v"); + } + } + protected void addIncremental(boolean incremental, Vector args) { + } + protected void addMap(boolean map, Vector args) { + if (!map) { + args.addElement("-x"); + } + } + protected void addStack(int stack, Vector args) { + if (stack >= 0) { + String stackStr = Integer.toHexString(stack); + args.addElement("-S:" + stackStr); + } + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + public String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + public String getIdentifier() { + return "Borland Linker"; + } + public File[] getLibraryPath() { + return BorlandProcessor.getEnvironmentPath("ilink32", 'L', + new String[]{"..\\lib"}); + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return BorlandProcessor.getLibraryPatterns(libnames, libType); + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return BorlandLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } + public int getMaximumCommandLength() { + return 1024; + } + public String[] getOutputFileSwitch(String outFile) { + return BorlandProcessor.getOutputFileSwitch(outFile); + } + protected String getStartupObject(LinkType linkType) { + if (linkType.isSharedLibrary()) { + return "c0d32.obj"; + } + if (linkType.isSubsystemGUI()) { + return "c0w32.obj"; + } + if (linkType.isSubsystemConsole()) { + return "c0x32.obj"; + } + return null; + } + public boolean isCaseSensitive() { + return BorlandProcessor.isCaseSensitive(); + } + /** + * Prepares argument list for exec command. + * + * @param outputDir linker output directory + * @param outputName linker output name + * @param sourceFiles + * linker input files (.obj, .o, .res) + * @param config + * linker configuration + * @return arguments for runTask + */ + protected String[] prepareArguments( + CCTask task, + String outputDir, + String outputName, + String[] sourceFiles, + CommandLineLinkerConfiguration config) { + String[] preargs = config.getPreArguments(); + String[] endargs = config.getEndArguments(); + Vector execArgs = new Vector(preargs.length + endargs.length + 10 + + sourceFiles.length); + execArgs.addElement(this.getCommand()); + for (int i = 0; i < preargs.length; i++) { + execArgs.addElement(preargs[i]); + } + for (int i = 0; i < endargs.length; i++) { + execArgs.addElement(endargs[i]); + } + // + // see if the input files have any known startup obj files + // + String startup = null; + for (int i = 0; i < sourceFiles.length; i++) { + String filename = new File(sourceFiles[i]).getName().toLowerCase(); + if (startup != null && filename.substring(0, 2).equals("c0") + && filename.substring(3, 5).equals("32") + && filename.substring(filename.length() - 4).equals(".obj")) { + startup = sourceFiles[i]; + } + } + // + // c0w32.obj, c0x32.obj or c0d32.obj depending on + // link type + if (startup == null) { + startup = config.getStartupObject(); + } + execArgs.addElement(startup); + Vector resFiles = new Vector(); + Vector libFiles = new Vector(); + String defFile = null; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < sourceFiles.length; i++) { + String last4 = sourceFiles[i] + .substring(sourceFiles[i].length() - 4).toLowerCase(); + if (last4.equals(".def")) { + defFile = quoteFilename(buf, sourceFiles[i]); + } else { + if (last4.equals(".res")) { + resFiles.addElement(quoteFilename(buf, sourceFiles[i])); + } else { + if (last4.equals(".lib")) { + libFiles.addElement(quoteFilename(buf, sourceFiles[i])); + } else { + execArgs.addElement(quoteFilename(buf, sourceFiles[i])); + } + } + } + } + // + // output file name + // + String outputFileName = new File(outputDir, outputName).toString(); + execArgs.addElement("," + quoteFilename(buf, outputFileName)); + if (config.getMap()) { + int lastPeriod = outputFileName.lastIndexOf('.'); + String mapName; + if (lastPeriod < outputFileName.length() - 4) { + mapName = outputFileName + ".map"; + } else { + mapName = outputFileName.substring(0, lastPeriod) + ".map"; + } + execArgs.addElement("," + quoteFilename(buf, mapName) + ","); + } else { + execArgs.addElement(",,"); + } + // + // add all the libraries + // + Enumeration libEnum = libFiles.elements(); + boolean hasImport32 = false; + boolean hasCw32 = false; + while (libEnum.hasMoreElements()) { + String libName = (String) libEnum.nextElement(); + if (libName.equalsIgnoreCase("import32.lib")) { + hasImport32 = true; + } + if (libName.equalsIgnoreCase("cw32.lib")) { + hasImport32 = true; + } + execArgs.addElement(quoteFilename(buf, libName)); + } + if (!hasCw32) { + execArgs.addElement(quoteFilename(buf, "cw32.lib")); + } + if (!hasImport32) { + execArgs.addElement(quoteFilename(buf, "import32.lib")); + } + if (defFile == null) { + execArgs.addElement(",,"); + } else { + execArgs.addElement("," + quoteFilename(buf, defFile) + ","); + } + Enumeration resEnum = resFiles.elements(); + while (resEnum.hasMoreElements()) { + String resName = (String) resEnum.nextElement(); + execArgs.addElement(quoteFilename(buf, resName)); + } + String[] execArguments = new String[execArgs.size()]; + execArgs.copyInto(execArguments); + return execArguments; + } + /** + * Prepares argument list to execute the linker using a response file. + * + * @param outputFile + * linker output file + * @param args + * output of prepareArguments + * @return arguments for runTask + */ + protected String[] prepareResponseFile(File outputFile, String[] args) + throws IOException { + String cmdargs[] = BorlandProcessor.prepareResponseFile(outputFile, args, " + \n"); + cmdargs[cmdargs.length - 1] = getCommandFileSwitch(cmdargs[cmdargs.length -1]); + return cmdargs; + } + + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + */ + public void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) throws IOException { + WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java new file mode 100644 index 0000000..b14c854 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java @@ -0,0 +1,219 @@ +/* + * + * Copyright 2002-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; +import java.io.FileWriter; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +/** + * A add-in class for Borland(r) processor adapters + * + * + */ +public final class BorlandProcessor { + public static void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("-w-"); + break; + case 5 : + args.addElement("-w!"); + break; + default : + args.addElement("-w"); + break; + } + } + public static void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("-D"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + /** + * This method extracts path information from the appropriate .cfg file in + * the install directory. + * + * @param toolName + * Tool name, for example, "bcc32", "brc32", "ilink32" + * @param switchChar + * Command line switch character, for example "L" for libraries + * @param defaultRelativePath + * default path relative to executable directory + * @return path + */ + public static File[] getEnvironmentPath(String toolName, char switchChar, + String[] defaultRelativePath) { + if (toolName == null) { + throw new NullPointerException("toolName"); + } + if (defaultRelativePath == null) { + throw new NullPointerException("defaultRelativePath"); + } + String[] path = defaultRelativePath; + File exeDir = CUtil.getExecutableLocation(toolName + ".exe"); + if (exeDir != null) { + File cfgFile = new File(exeDir, toolName + ".cfg"); + if (cfgFile.exists()) { + try { + Reader reader = new BufferedReader(new FileReader(cfgFile)); + BorlandCfgParser cfgParser = new BorlandCfgParser( + switchChar); + path = cfgParser.parsePath(reader); + reader.close(); + } catch (IOException ex) { + // + // could be logged + // + } + } + } else { + // + // if can't find the executable, + // assume current directory to resolve relative paths + // + exeDir = new File(System.getProperty("user.dir")); + } + int nonExistant = 0; + File[] resourcePath = new File[path.length]; + for (int i = 0; i < path.length; i++) { + resourcePath[i] = new File(path[i]); + if (!resourcePath[i].isAbsolute()) { + resourcePath[i] = new File(exeDir, path[i]); + } + // + // if any of the entries do not exist or are + // not directories, null them out + if (!(resourcePath[i].exists() && resourcePath[i].isDirectory())) { + resourcePath[i] = null; + nonExistant++; + } + } + // + // if there were some non-existant or non-directory + // entries in the configuration file then + // create a shorter array + if (nonExistant > 0) { + File[] culled = new File[resourcePath.length - nonExistant]; + int index = 0; + for (int i = 0; i < resourcePath.length; i++) { + if (resourcePath[i] != null) { + culled[index++] = resourcePath[i]; + } + } + resourcePath = culled; + } + return resourcePath; + } + public static String getIncludeDirSwitch(String includeOption, + String includeDir) { + StringBuffer buf = new StringBuffer(includeOption); + quoteFile(buf, includeDir); + return buf.toString(); + } + public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length]; + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(libnames[i]); + buf.append(".lib"); + patterns[i] = buf.toString(); + } + return patterns; + } + public static String[] getOutputFileSwitch(String outFile) { + return new String[0]; + } + public static void getUndefineSwitch(StringBuffer buffer, String define) { + buffer.append("-U"); + buffer.append(define); + } + public static boolean isCaseSensitive() { + return false; + } + public static void quoteFile(StringBuffer buf, String outPath) { + if (outPath.charAt(0) != '\"' + && (outPath.indexOf(' ') >= 0 + || outPath.indexOf('-') >= 0 + || outPath.indexOf('/') >= 0)) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + } + + /** + * Prepares argument list to execute the linker using a response file. + * + * @param outputFile + * linker output file + * @param args + * output of prepareArguments + * @return arguments for runTask + */ + public static String[] prepareResponseFile(File outputFile, + String[] args, + String continuation) + throws IOException { + String baseName = outputFile.getName(); + File commandFile = new File(outputFile.getParent(), baseName + ".rsp"); + FileWriter writer = new FileWriter(commandFile); + for (int i = 1; i < args.length - 1; i++) { + writer.write(args[i]); + // + // if either the current argument ends with + // or next argument starts with a comma then + // don't split the line + if (args[i].endsWith(",") || args[i + 1].startsWith(",")) { + writer.write(' '); + } else { + // + // split the line to make it more readable + // + writer.write(continuation); + } + } + // + // write the last argument + // + if (args.length > 1) { + writer.write(args[args.length - 1]); + } + writer.close(); + String[] execArgs = new String[2]; + execArgs[0] = args[0]; + // + // left for the caller to decorate + execArgs[1] = commandFile.toString(); + return execArgs; + } + + private BorlandProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java new file mode 100644 index 0000000..debfa2b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java @@ -0,0 +1,129 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import java.io.File; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Borland(r) brc32 Resource compiler. + * + * @author Curt Arnold + */ +public class BorlandResourceCompiler extends CommandLineCompiler { + private static final BorlandResourceCompiler instance = new BorlandResourceCompiler( + false, null); + public static BorlandResourceCompiler getInstance() { + return instance; + } + private BorlandResourceCompiler(boolean newEnvironment, Environment env) { + super("brc32", "c:\\__bogus\\__bogus.rc", new String[]{".rc"}, + new String[]{".h", ".hpp", ".inl"}, ".res", false, null, + newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + // + // compile only + // + args.addElement("-r"); + } + protected void addWarningSwitch(Vector args, int level) { + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new BorlandResourceCompiler(newEnvironment, env); + } + return this; + } + public void compile(CCTask task, File outputDir, String[] sourceFiles, + String[] args, String[] endArgs, boolean relentless, + CommandLineCompilerConfiguration config, ProgressMonitor monitor) + throws BuildException { + super.compile(task, outputDir, sourceFiles, args, endArgs, relentless, + config, monitor); + } + /** + * The include parser for C will work just fine, but we didn't want to + * inherit from CommandLineCCompiler + */ + protected Parser createParser(File source) { + return new CParser(); + } + protected int getArgumentCountPerInputFile() { + return 2; + } + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("-d"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + protected File[] getEnvironmentIncludePath() { + return BorlandProcessor.getEnvironmentPath("brc32", 'i', + new String[]{"..\\include"}); + } + protected String getIncludeDirSwitch(String includeDir) { + return BorlandProcessor.getIncludeDirSwitch("-i", includeDir); + } + protected String getInputFileArgument(File outputDir, String filename, + int index) { + if (index == 0) { + String[] outputFileNames = getOutputFileNames(filename, null); + String fullOutputName = new File(outputDir, outputFileNames[0]) + .toString(); + return "-fo" + fullOutputName; + } + return filename; + } + public Linker getLinker(LinkType type) { + return BorlandLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 1024; + } + protected int getMaximumInputFilesPerCommand() { + return 1; + } + protected int getTotalArgumentLengthForInputFile(File outputDir, + String inputFile) { + String arg1 = getInputFileArgument(outputDir, inputFile, 0); + String arg2 = getInputFileArgument(outputDir, inputFile, 1); + return arg1.length() + arg2.length() + 2; + } + protected void getUndefineSwitch(StringBuffer buffer, String define) { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java new file mode 100644 index 0000000..dfe5ec6 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/CBuilderXProjectWriter.java @@ -0,0 +1,542 @@ +/* + * + * Copyright 2004-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks.borland; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; +import net.sf.antcontrib.cpptasks.ide.ProjectDef; +import net.sf.antcontrib.cpptasks.ide.ProjectWriter; + +import org.apache.tools.ant.BuildException; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.Serializer; +import org.apache.xml.serialize.XMLSerializer; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Writes a CBuilderX 1.0 project file. + * + * @author curta + * + */ +public final class CBuilderXProjectWriter + implements ProjectWriter { + /** + * Constructor. + */ + public CBuilderXProjectWriter() { + } + + /** + * Writes a project definition file. + * + * @param fileName + * project name for file, should has .cbx extension + * @param task + * cc task for which to write project + * @param projectDef + * project element + * @param sources source files + * @param targets compilation targets + * @param linkTarget link target + * @throws IOException if I/O error + * @throws SAXException if XML serialization error + */ + public void writeProject(final File fileName, + final CCTask task, + final ProjectDef projectDef, + final List sources, + final Hashtable targets, + final TargetInfo linkTarget) throws + IOException, + SAXException { + + String projectName = projectDef.getName(); + if (projectName == null) { + projectName = fileName.getName(); + } + final String basePath = fileName.getAbsoluteFile().getParent(); + + File projectFile = new File(fileName + ".cbx"); + if (!projectDef.getOverwrite() && projectFile.exists()) { + throw new BuildException("Not allowed to overwrite project file " + + projectFile.toString()); + } + + CommandLineCompilerConfiguration compilerConfig = + getBaseCompilerConfiguration(targets); + if (compilerConfig == null) { + throw new BuildException( + "Unable to generate C++ BuilderX project when gcc or bcc is not used."); + } + + OutputStream outStream = new FileOutputStream(projectFile); + OutputFormat format = new OutputFormat("xml", "UTF-8", true); + Serializer serializer = new XMLSerializer(outStream, format); + ContentHandler content = serializer.asContentHandler(); + content.startDocument(); + AttributesImpl emptyAttrs = new AttributesImpl(); + content.startElement(null, "project", "project", emptyAttrs); + PropertyWriter propertyWriter = new PropertyWriter(content); + propertyWriter.write("build.config", "active", "0"); + propertyWriter.write("build.config", "count", "0"); + propertyWriter.write("build.config", "excludedefaultforzero", "0"); + propertyWriter.write("build.config.0", "builddir", "Debug"); + propertyWriter.write("build.config.0", "key", "Debug_Build"); + propertyWriter.write("build.config.0", "linux.builddir", + "linux/Debug_Build"); + propertyWriter.write("build.config.0", "settings.MinGW", + "default;debug"); + propertyWriter.write("build.config.0", "settings.gnuc++", + "default;debug"); + propertyWriter.write("build.config.0", "settings.intellinia32", + "default;debug"); + propertyWriter.write("build.config.0", "settings.mswin32", + "default;debug"); + propertyWriter.write("build.config.0", "type", "Toolset"); + propertyWriter.write("build.config.0", "win32.builddir", + "windows/Debug_Build"); + propertyWriter.write("build.node", "name", projectDef.getName()); + final String buildType = getBuildType(task); + propertyWriter.write("build.node", "type", buildType); + propertyWriter.write("build.platform", "active", + getActivePlatform(task)); + propertyWriter.write("build.platform", "linux.Debug_Build.toolset", + "gnuc++"); + propertyWriter.write("build.platform", "linux.Release_Build.toolset", + "gnuc++"); + propertyWriter.write("build.platform", "linux.default", "gnuc++"); + propertyWriter.write("build.platform", "linux.gnuc++.enabled", "1"); + propertyWriter.write("build.platform", "linux.mswin32.enabled", "1"); + propertyWriter.write("build.platform", "linux.win32b.enabled", "1"); + propertyWriter.write("build.platform", "solaris.default", "gnuc++"); + propertyWriter.write("build.platform", "solaris.enabled", "1"); + String toolset = getWin32Toolset(compilerConfig); + propertyWriter.write("build.platform", "win32.default", toolset); + propertyWriter.write("build.platform", "win32." + toolset + ".enabled", "1"); + + propertyWriter.write("cbproject", "version", "X.1.0"); + if ("dllproject".equals(buildType)) { + propertyWriter.write("gnuc++.g++compile", + "option.fpic_using_GOT.enabled", "1"); + propertyWriter.write("gnuc++.g++link", "option.shared.enabled", "1"); + propertyWriter.write("intellinia32.icc", "option.minus_Kpic.enabled", + "1"); + propertyWriter.write("intellinia32.icclink", + "option.minus_shared.enabled", "1"); + } + // + // assume the first target is representative of all compilation tasks + // + writeCompileOptions(basePath, propertyWriter, compilerConfig); + writeLinkOptions(basePath, propertyWriter, linkTarget); + propertyWriter.write("linux.gnuc++.Debug_Build", "saved", "1"); + if ("dllproject".equals(buildType)) { + propertyWriter.write("runtime", "ExcludeDefaultForZero", "1"); + //propertyWriter.write("unique", "id", "852"); + } else if ("exeproject".equals(buildType)) { + propertyWriter.write("runtime.0", "BuildTargetOnRun", + "com.borland.cbuilder.build." + + "CBProjectBuilder$ProjectBuildAction;make"); + propertyWriter.write("runtime.0", "ConfigurationName", + projectDef.getName()); + propertyWriter.write("runtime.0", "RunnableType", + "com.borland.cbuilder.runtime.ExecutableRunner"); + } + AttributesImpl fileAttributes = new AttributesImpl(); + fileAttributes.addAttribute(null, "path", "path", "#PCDATA", ""); + AttributesImpl gccAttributes = null; + if (!"g++".equals(compilerConfig.getCommand())) { + gccAttributes = new AttributesImpl(); + gccAttributes.addAttribute(null, "category", "category", "#PCDATA", + "build.basecmd"); + gccAttributes.addAttribute(null, "name", "name", "#PCDATA", + "linux.gnuc++.Debug_Build.g++_key"); + gccAttributes.addAttribute(null, "value", "value", "#PCDATA", + compilerConfig.getCommand()); + } + + Iterator targetIter = targets.values().iterator(); + while (targetIter.hasNext()) { + TargetInfo info = (TargetInfo) targetIter.next(); + File[] targetsources = info.getSources(); + for (int i = 0; i < targetsources.length; i++) { + String relativePath = CUtil.getRelativePath(basePath, + targetsources[i]); + fileAttributes.setValue(0, relativePath); + content.startElement(null, "file", "file", fileAttributes); + + // + // if file ends with .c, use gcc instead of g++ + // + if (gccAttributes != null) { + content.startElement(null, "property", "property", gccAttributes); + content.endElement(null, "property", "property"); + } + content.endElement(null, "file", "file"); + } + } + content.endElement(null, "project", "project"); + content.endDocument(); + } + + /** + * Gets build type from link target. + * @param task CCTask current task + * @return String build type + */ + private String getBuildType(final CCTask task) { + String outType = task.getOuttype(); + if ("executable".equals(outType)) { + return "exeproject"; + } else if ("static".equals(outType)) { + return "libraryproject"; + } + return "dllproject"; + } + + /** + * Gets active platform. + * @param task CCTask cc task + * @return String platform identifier + */ + private String getActivePlatform(final CCTask task) { + String osName = System.getProperty("os.name").toLowerCase(Locale.US); + if (osName.indexOf("windows") >= 0) { + return "win32"; + } + return "linux"; + } + + private String getWin32Toolset(final CommandLineCompilerConfiguration compilerConfig) { + if (compilerConfig != null && compilerConfig.getCompiler() instanceof BorlandCCompiler) { + return "win32b"; + } + return "MinGW"; + } + + /** + * Utility class to generate property elements. + */ + private static class PropertyWriter { + /** + * Content handler. + */ + private ContentHandler content; + + /** + * Attributes list. + */ + private AttributesImpl propertyAttributes; + + /** + * Constructor. + * + * @param contentHandler ContentHandler content handler + */ + public PropertyWriter(final ContentHandler contentHandler) { + content = contentHandler; + propertyAttributes = new AttributesImpl(); + propertyAttributes.addAttribute(null, "category", "category", + "#PCDATA", ""); + propertyAttributes + .addAttribute(null, "name", "name", "#PCDATA", ""); + propertyAttributes.addAttribute(null, "value", "value", "#PCDATA", + ""); + } + + /** + * Write property element. + * + * @param category String category + * @param name String property name + * @param value String property value + * @throws SAXException if I/O error or illegal content + */ + public final void write(final String category, + final String name, + final String value) throws SAXException { + propertyAttributes.setValue(0, category); + propertyAttributes.setValue(1, name); + propertyAttributes.setValue(2, value); + content.startElement(null, "property", "property", + propertyAttributes); + content.endElement(null, "property", "property"); + } + } + + /** + * Gets the first recognized compiler from the + * compilation targets. + * @param targets compilation targets + * @return representative (hopefully) compiler configuration + */ + private CommandLineCompilerConfiguration + getBaseCompilerConfiguration(final Hashtable targets) { + // + // find first target with an gcc or bcc compilation + // + CommandLineCompilerConfiguration compilerConfig = null; + // + // get the first target and assume that it is representative + // + Iterator targetIter = targets.values().iterator(); + while (targetIter.hasNext()) { + TargetInfo targetInfo = (TargetInfo) targetIter.next(); + ProcessorConfiguration config = targetInfo.getConfiguration(); + String identifier = config.getIdentifier(); + // + // for the first gcc or bcc compiler + // + if (config instanceof CommandLineCompilerConfiguration) { + compilerConfig = (CommandLineCompilerConfiguration) config; + if (compilerConfig.getCompiler() instanceof GccCCompiler || + compilerConfig.getCompiler() instanceof BorlandCCompiler) { + return compilerConfig; + } + } + } + return null; + } + + /** + * Writes elements corresponding to compilation options. + * + * @param baseDir String base directory + * @param writer PropertyWriter property writer + * @param compilerConfig representative configuration + * @throws SAXException if I/O error or illegal content + */ + private void writeCompileOptions(final String baseDir, + final PropertyWriter writer, + final CommandLineCompilerConfiguration + compilerConfig) throws SAXException { + boolean isBcc = false; + boolean isUnix = true; + String compileID = "linux.Debug_Build.gnuc++.g++compile"; + if (compilerConfig.getCompiler() instanceof BorlandCCompiler) { + compileID = "win32.Debug_Build.win32b.bcc32"; + isUnix = false; + isBcc = true; + } + + File[] includePath = compilerConfig.getIncludePath(); + int includeIndex = 1; + if (isUnix) { + writer.write(compileID, + "option.I.arg." + (includeIndex++), + "/usr/include"); + writer.write(compileID, + "option.I.arg." + (includeIndex++), + "/usr/include/g++-3"); + } + for (int i = 0; i < includePath.length; i++) { + String relPath = CUtil.getRelativePath(baseDir, includePath[i]); + writer.write(compileID, + "option.I.arg." + (includeIndex++), + relPath); + } + if (includePath.length > 0) { + writer.write(compileID, + "option.I.enabled", + "1"); + } + + String defineBase = "option.D_MACRO_VALUE"; + if (isBcc) { + defineBase = "option.D"; + } + String defineOption = defineBase + ".arg."; + int defineIndex = 1; + int undefineIndex = 1; + String[] preArgs = compilerConfig.getPreArguments(); + for (int i = 0; i < preArgs.length; i++) { + if (preArgs[i].startsWith("-D")) { + writer.write(compileID, + defineOption + (defineIndex++), + preArgs[i].substring(2)); + } else if (preArgs[i].startsWith("-U")) { + writer.write(compileID, + "option.U.arg." + + (undefineIndex++), preArgs[i] + .substring(2)); + } else if (!(preArgs[i].startsWith("-I") + || preArgs[i].startsWith("-o"))) { + // + // any others (-g, -fno-rtti, -w, -Wall, etc) + // + writer.write(compileID, + "option." + preArgs[i].substring(1) + ".enabled", + "1"); + } + } + if (defineIndex > 1) { + writer.write(compileID, + defineBase + ".enabled", + "1"); + } + if (undefineIndex > 1) { + writer.write(compileID, + "option.U.enabled", + "1"); + } + } + + /** + * Writes elements corresponding to link options. + * + * @param baseDir String base directory + * @param writer PropertyWriter property writer + * @param linkTarget TargetInfo link target + * @throws SAXException if I/O error or illegal content + */ + private void + writeLinkOptions(final String baseDir, + final PropertyWriter writer, + final TargetInfo linkTarget) throws SAXException { + if (linkTarget != null) { + ProcessorConfiguration config = linkTarget.getConfiguration(); + if (config instanceof CommandLineLinkerConfiguration) { + CommandLineLinkerConfiguration linkConfig = + (CommandLineLinkerConfiguration) config; + + if (linkConfig.getLinker() instanceof BorlandLinker) { + String linkID = "win32.Debug_Build.win32b.ilink32"; + writeIlinkArgs(writer, linkID, linkConfig.getPreArguments()); + writeIlinkArgs(writer, linkID, linkConfig.getEndArguments()); + writer.write(linkID, "param.libfiles.1", "cw32mt.lib"); + writer.write(linkID, "param.libfiles.2", "import32.lib"); + int libIndex = 3; + String[] libNames = linkConfig.getLibraryNames(); + for(int i = 0; i < libNames.length; i++) { + writer.write(linkID, "param.libfiles." + (libIndex++), + libNames[i]); + } + String startup = linkConfig.getStartupObject(); + if (startup != null) { + writer.write(linkID, "param.objfiles.1", startup); + } + } else { + String linkID = "linux.Debug_Build.gnuc++.g++link"; + writeLdArgs(writer, linkID, linkConfig.getPreArguments()); + writeLdArgs(writer, linkID, linkConfig.getEndArguments()); + } + } + } + } + + /** + * Writes ld linker options to project file. + * + * @param writer PropertyWriter property writer + * @param linkID String linker identifier + * @param preArgs String[] linker arguments + * @throws SAXException thrown if unable to write option + */ + private void writeLdArgs(final PropertyWriter writer, + final String linkID, + final String[] preArgs) throws SAXException { + int objnameIndex = 1; + int libnameIndex = 1; + int libpathIndex = 1; + for (int i = 0; i < preArgs.length; i++) { + if (preArgs[i].startsWith("-o")) { + writer.write(linkID, + "option.o.arg." + + (objnameIndex++), preArgs[i] + .substring(2)); + } else if (preArgs[i].startsWith("-l")) { + writer.write(linkID, + "option.l.arg." + + (libnameIndex++), preArgs[i] + .substring(2)); + } else if (preArgs[i].startsWith("-L")) { + writer.write(linkID, + "option.L.arg." + + (libpathIndex++), preArgs[i] + .substring(2)); + } else { + // + // any others + // + writer.write(linkID, "option." + preArgs[i].substring(1) + ".enabled", + "1"); + } + } + if (objnameIndex > 1) { + writer.write(linkID, + "option.o.enabled", + "1"); + } + if (libnameIndex > 1) { + writer.write(linkID, + "option.l.enabled", + "1"); + } + if (libpathIndex > 1) { + writer.write(linkID, + "option.L.enabled", + "1"); + } + } + + /** + * Writes ilink32 linker options to project file. + * + * @param writer PropertyWriter property writer + * @param linkID String linker identifier + * @param preArgs String[] linker arguments + * @throws SAXException thrown if unable to write option + */ + private void writeIlinkArgs(final PropertyWriter writer, + final String linkID, + final String[] args) throws SAXException { + for (int i = 0; i < args.length; i++) { + if (args[i].charAt(0) == '/' || args[i].charAt(0) == '-') { + int equalsPos = args[i].indexOf('='); + if (equalsPos > 0) { + String option = "option." + args[i].substring(0, equalsPos -1); + writer.write(linkID, + option + ".enabled", + "1"); + writer.write(linkID, + option + ".value", + args[i].substring(equalsPos + 1)); + } else { + writer.write(linkID, "option." + args[i].substring(1) + ".enabled", "1"); + } + } + } + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java new file mode 100644 index 0000000..82767cb --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java @@ -0,0 +1,46 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import net.sf.antcontrib.cpptasks.parser.AbstractParser; +import net.sf.antcontrib.cpptasks.parser.AbstractParserState; +import net.sf.antcontrib.cpptasks.parser.FilenameState; +public class CfgFilenameState extends FilenameState { + private char terminator; + public CfgFilenameState(AbstractParser parser, char[] terminators) { + super(parser, terminators); + terminator = terminators[0]; + } + public AbstractParserState consume(char ch) { + // + // if a ';' is encountered then + // close the previous filename by sending a + // recognized terminator to our super class + // and stay in this state for more filenamese + if (ch == ';') { + super.consume(terminator); + return this; + } + AbstractParserState newState = super.consume(ch); + // + // change null (consume to end of line) + // to look for next switch character + if (newState == null) { + newState = getParser().getNewLineState(); + } + return newState; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java new file mode 100644 index 0000000..5656af8 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java @@ -0,0 +1,30 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import net.sf.antcontrib.cpptasks.parser.AbstractParser; +import net.sf.antcontrib.cpptasks.parser.AbstractParserState; +public class ConsumeToSpaceOrNewLine extends AbstractParserState { + public ConsumeToSpaceOrNewLine(AbstractParser parser) { + super(parser); + } + public AbstractParserState consume(char ch) { + if (ch == ' ' || ch == '\t' || ch == '\n') { + return getParser().getNewLineState(); + } + return this; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java new file mode 100644 index 0000000..ec3bc84 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java @@ -0,0 +1,35 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import net.sf.antcontrib.cpptasks.parser.AbstractParser; +import net.sf.antcontrib.cpptasks.parser.AbstractParserState; +public class QuoteBranchState extends AbstractParserState { + private AbstractParserState quote; + private AbstractParserState unquote; + public QuoteBranchState(AbstractParser parser, AbstractParserState quote, + AbstractParserState unquote) { + super(parser); + this.quote = quote; + this.unquote = unquote; + } + public AbstractParserState consume(char ch) { + if (ch == '"') { + return quote; + } + return unquote.consume(ch); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/package.html b/src/main/java/net/sf/antcontrib/cpptasks/borland/package.html new file mode 100644 index 0000000..a91e91f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/package.html @@ -0,0 +1,27 @@ + + + + + + + +Adapter for Borland tools. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java new file mode 100644 index 0000000..1595ae1 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java @@ -0,0 +1,137 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compaq; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineFortranCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Compaq(r) Visual Fortran compiler. + * + * @author Curt Arnold + */ +public class CompaqVisualFortranCompiler extends CommandLineFortranCompiler { + private static final CompaqVisualFortranCompiler[] instance = new CompaqVisualFortranCompiler[]{new CompaqVisualFortranCompiler( + false, null)}; + public static CompaqVisualFortranCompiler getInstance() { + return instance[0]; + } + private CompaqVisualFortranCompiler(boolean newEnvironment, Environment env) { + super("DF", null, new String[]{".f90", ".for", ".f"}, new String[]{ + ".i", ".i90", ".fpp", ".inc", ".bak", ".exe"}, ".obj", false, + null, newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("/nologo"); + args.addElement("/compile_only"); + if (debug) { + args.addElement("/debug:full"); + args.addElement("/define:_DEBUG"); + } else { + args.addElement("/debug:none"); + args.addElement("/define:NDEBUG"); + } + if (multithreaded) { + args.addElement("/threads"); + args.addElement("/define:_MT"); + } else { + args.addElement("/nothreads"); + } + boolean staticRuntime = linkType.isStaticRuntime(); + if (staticRuntime) { + args.addElement("/libs:static"); + } else { + args.addElement("/libs:dll"); + } + if (linkType.isSharedLibrary()) { + args.addElement("/dll"); + args.addElement("/define:_DLL"); + } + } + public void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("/nowarn"); + break; + case 1 : + break; + case 2 : + break; + case 3 : + args.addElement("/warn:usage"); + break; + case 4 : + args.addElement("/warn:all"); + break; + case 5 : + args.addElement("/warn:errors"); + break; + } + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new CompaqVisualFortranCompiler(newEnvironment, env); + } + return this; + } + protected void getDefineSwitch(StringBuffer buf, String define, String value) { + buf.append("/define:"); + buf.append(define); + if (value != null && value.length() > 0) { + buf.append('='); + buf.append(value); + } + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ";"); + } + protected String getIncludeDirSwitch(String includeDir) { + StringBuffer buf = new StringBuffer("/include:"); + if (includeDir.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(includeDir); + buf.append('"'); + } else { + buf.append(includeDir); + } + return buf.toString(); + } + public Linker getLinker(LinkType type) { + return CompaqVisualFortranLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 1024; + } + protected void getUndefineSwitch(StringBuffer buf, String define) { + buf.append("/undefine:"); + buf.append(define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java new file mode 100644 index 0000000..2488619 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java @@ -0,0 +1,82 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compaq; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioLibrarian; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioProcessor; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for the Compaq(r) Visual Fortran Librarian + * + * @author Curt Arnold + */ +public class CompaqVisualFortranLibrarian extends CommandLineLinker { + private static final CompaqVisualFortranLibrarian instance = new CompaqVisualFortranLibrarian(); + public static CompaqVisualFortranLibrarian getInstance() { + return instance; + } + private CompaqVisualFortranLibrarian() { + super("lib", "/bogus", new String[]{".obj"}, new String[0], ".lib", + false, null); + } + protected void addBase(long base, Vector args) { + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + args.addElement("/nologo"); + } + protected void addIncremental(boolean incremental, Vector args) { + } + protected void addMap(boolean map, Vector args) { + } + protected void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + protected String getCommandFileSwitch(String commandFile) { + return DevStudioProcessor.getCommandFileSwitch(commandFile); + } + public File[] getLibraryPath() { + return new File[0]; + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return new String[0]; + } + public Linker getLinker(LinkType type) { + return CompaqVisualFortranLinker.getInstance().getLinker(type); + } + protected int getMaximumCommandLength() { + return DevStudioLibrarian.getInstance().getMaximumCommandLength(); + } + protected String[] getOutputFileSwitch(String outputFile) { + return DevStudioLibrarian.getInstance().getOutputFileSwitch(outputFile); + } + public boolean isCaseSensitive() { + return false; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java new file mode 100644 index 0000000..c8930f9 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java @@ -0,0 +1,77 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compaq; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLinker; +/** + * Adapter for the Compaq(r) Visual Fortran linker. + * + * @author Curt Arnold + */ +public final class CompaqVisualFortranLinker extends DevStudioCompatibleLinker { + private static final CompaqVisualFortranLinker dllLinker = new CompaqVisualFortranLinker( + ".dll"); + private static final CompaqVisualFortranLinker instance = new CompaqVisualFortranLinker( + ".exe"); + public static CompaqVisualFortranLinker getInstance() { + return instance; + } + private CompaqVisualFortranLinker(String outputSuffix) { + super("DF", "__bogus__.xxx", outputSuffix); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + args.addElement("/NOLOGO"); + boolean staticRuntime = linkType.isStaticRuntime(); + if (staticRuntime) { + args.addElement("/libs:static"); + } else { + args.addElement("/libs:dll"); + } + if (debug) { + args.addElement("/debug"); + } else { + } + if (linkType.isSharedLibrary()) { + args.addElement("/dll"); + } else { + args.addElement("/exe"); + } + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return CompaqVisualFortranLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } + public String[] getOutputFileSwitch(String outputFile) { + StringBuffer buf = new StringBuffer("/OUT:"); + if (outputFile.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(outputFile); + buf.append('"'); + } else { + buf.append(outputFile); + } + return new String[]{buf.toString()}; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java new file mode 100644 index 0000000..2d1401f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java @@ -0,0 +1,207 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.CompilerDef; +import net.sf.antcontrib.cpptasks.DependencyInfo; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.TargetDef; +import net.sf.antcontrib.cpptasks.VersionInfo; + +/** + * An abstract compiler implementation. + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public abstract class AbstractCompiler extends AbstractProcessor + implements + Compiler { + private static final String[] emptyIncludeArray = new String[0]; + private String outputSuffix; + protected AbstractCompiler(String[] sourceExtensions, + String[] headerExtensions, String outputSuffix) { + super(sourceExtensions, headerExtensions); + this.outputSuffix = outputSuffix; + } + /** + * Checks file name to see if parse should be attempted + * + * Default implementation returns false for files with extensions '.dll', + * 'tlb', '.res' + * + */ + protected boolean canParse(File sourceFile) { + String sourceName = sourceFile.toString(); + int lastPeriod = sourceName.lastIndexOf('.'); + if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) { + String ext = sourceName.substring(lastPeriod).toUpperCase(); + if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) { + return false; + } + } + return true; + } + abstract protected CompilerConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef[] baseConfigs, + CompilerDef specificConfig, TargetDef targetPlatform, + VersionInfo versionInfo); + public ProcessorConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef[] baseConfigs, + ProcessorDef specificConfig, TargetDef targetPlatform, + VersionInfo versionInfo) { + if (specificConfig == null) { + throw new NullPointerException("specificConfig"); + } + return createConfiguration(task, linkType, baseConfigs, + (CompilerDef) specificConfig, targetPlatform, versionInfo); + } + abstract protected Parser createParser(File sourceFile); + protected String getBaseOutputName(String inputFile) { + int lastSlash = inputFile.lastIndexOf('/'); + int lastReverse = inputFile.lastIndexOf('\\'); + int lastSep = inputFile.lastIndexOf(File.separatorChar); + if (lastReverse > lastSlash) { + lastSlash = lastReverse; + } + if (lastSep > lastSlash) { + lastSlash = lastSep; + } + int lastPeriod = inputFile.lastIndexOf('.'); + if (lastPeriod < 0) { + lastPeriod = inputFile.length(); + } + return inputFile.substring(lastSlash + 1, lastPeriod); + } + public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) { + // + // if a recognized input file + // + if (bid(inputFile) > 1) { + String baseName = getBaseOutputName(inputFile); + return new String[] { baseName + outputSuffix }; + } + return new String[0]; + } + /** + * Returns dependency info for the specified source file + * + * @param task + * task for any diagnostic output + * @param source + * file to be parsed + * @param includePath + * include path to be used to resolve included files + * + * @param sysIncludePath + * sysinclude path from build file, files resolved using + * sysInclude path will not participate in dependency analysis + * + * @param envIncludePath + * include path from environment variable, files resolved with + * envIncludePath will not participate in dependency analysis + * + * @param baseDir + * used to produce relative paths in DependencyInfo + * @param includePathIdentifier + * used to distinguish DependencyInfo's from different include + * path settings + * + */ + public final DependencyInfo parseIncludes(CCTask task, File source, + File[] includePath, File[] sysIncludePath, File[] envIncludePath, + File baseDir, String includePathIdentifier) { + // + // if any of the include files can not be identified + // change the sourceLastModified to Long.MAX_VALUE to + // force recompilation of anything that depends on it + long sourceLastModified = source.lastModified(); + File[] sourcePath = new File[1]; + sourcePath[0] = new File(source.getParent()); + Vector onIncludePath = new Vector(); + Vector onSysIncludePath = new Vector(); + String baseDirPath; + try { + baseDirPath = baseDir.getCanonicalPath(); + } catch (IOException ex) { + baseDirPath = baseDir.toString(); + } + String relativeSource = CUtil.getRelativePath(baseDirPath, source); + String[] includes = emptyIncludeArray; + if (canParse(source)) { + Parser parser = createParser(source); + try { + Reader reader = new BufferedReader(new FileReader(source)); + parser.parse(reader); + includes = parser.getIncludes(); + } catch (IOException ex) { + task.log("Error parsing " + source.toString() + ":" + + ex.toString()); + includes = new String[0]; + } + } + for (int i = 0; i < includes.length; i++) { + String includeName = includes[i]; + if (!resolveInclude(includeName, sourcePath, onIncludePath)) { + if (!resolveInclude(includeName, includePath, onIncludePath)) { + if (!resolveInclude(includeName, sysIncludePath, + onSysIncludePath)) { + if (!resolveInclude(includeName, envIncludePath, + onSysIncludePath)) { + // + // this should be enough to require us to reparse + // the file with the missing include for dependency + // information without forcing a rebuild + sourceLastModified += 2 * CUtil.FILETIME_EPSILON; + } + } + } + } + } + for (int i = 0; i < onIncludePath.size(); i++) { + String relativeInclude = CUtil.getRelativePath(baseDirPath, + (File) onIncludePath.elementAt(i)); + onIncludePath.setElementAt(relativeInclude, i); + } + for (int i = 0; i < onSysIncludePath.size(); i++) { + String relativeInclude = CUtil.getRelativePath(baseDirPath, + (File) onSysIncludePath.elementAt(i)); + onSysIncludePath.setElementAt(relativeInclude, i); + } + return new DependencyInfo(includePathIdentifier, relativeSource, + sourceLastModified, onIncludePath, onSysIncludePath); + } + protected boolean resolveInclude(String includeName, File[] includePath, + Vector onThisPath) { + for (int i = 0; i < includePath.length; i++) { + File includeFile = new File(includePath[i], includeName); + if (includeFile.exists()) { + onThisPath.addElement(includeFile); + return true; + } + } + return false; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java new file mode 100644 index 0000000..5d9cefa --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java @@ -0,0 +1,122 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; +import java.io.IOException; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.LinkerDef; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.TargetDef; +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.types.Environment; +/** + * An abstract Linker implementation. + * + * @author Adam Murdoch + */ +public abstract class AbstractLinker extends AbstractProcessor + implements + Linker { + public AbstractLinker(String[] objExtensions, String[] ignoredExtensions) { + super(objExtensions, ignoredExtensions); + } + /** + * Returns the bid of the processor for the file. + * + * A linker will bid 1 on any unrecognized file type. + * + * @param inputFile + * filename of input file + * @return bid for the file, 0 indicates no interest, 1 indicates that the + * processor recognizes the file but doesn't process it (header + * files, for example), 100 indicates strong interest + */ + public int bid(String inputFile) { + int bid = super.bid(inputFile); + switch (bid) { + // + // unrecognized extension, take the file + // + case 0 : + return 1; + // + // discard the ignored extensions + // + case 1 : + return 0; + } + return bid; + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + return this; + } + abstract protected LinkerConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef[] baseConfigs, + LinkerDef specificConfig, TargetDef targetPlatform, + VersionInfo versionInfo); + public ProcessorConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef[] baseConfigs, + ProcessorDef specificConfig, + TargetDef targetPlatform, + VersionInfo versionInfo) { + if (specificConfig == null) { + throw new NullPointerException("specificConfig"); + } + return createConfiguration(task, linkType, baseConfigs, + (LinkerDef) specificConfig, targetPlatform, versionInfo); + } + public String getLibraryKey(File libfile) { + return libfile.getName(); + } + public abstract String[] getOutputFileNames(String fileName, VersionInfo versionInfo); + + + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + */ + public void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) throws IOException { + if (versionInfo == null) { + throw new NullPointerException("versionInfo"); + } + if (linkType == null) { + throw new NullPointerException("linkType"); + } + if (outputFile == null) { + throw new NullPointerException("outputFile"); + } + if (objDir == null) { + throw new NullPointerException("objDir"); + } + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java new file mode 100644 index 0000000..d0cd77b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java @@ -0,0 +1,129 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import org.apache.tools.ant.types.Environment; +/** + * An abstract processor (compiler/linker) implementation. + * + * @author Curt Arnold + */ +public abstract class AbstractProcessor implements Processor, Cloneable { + /** + * default bid for a file name that the processor recognizes but does not + * process and does not want to fall through to the linker + */ + public final static int DEFAULT_DISCARD_BID = 1; + /** + * default bid for a file name that the processor desires to process + */ + public final static int DEFAULT_PROCESS_BID = 100; + /** + * Determines the identification of a command line processor by capture the + * first line of its output for a specific command. + * + * @param command + * array of command line arguments starting with executable + * name. For example, { "cl" } + * @param fallback + * start of identifier if there is an error in executing the + * command + * @return identifier for the processor + */ + protected static String getIdentifier(String[] command, String fallback) { + String identifier = fallback; + try { + String[] cmdout = CaptureStreamHandler.run(command); + if (cmdout.length > 0) { + identifier = cmdout[0]; + } + } catch (Throwable ex) { + identifier = fallback + ":" + ex.toString(); + } + return identifier; + } + private final String[] headerExtensions; + private final String[] sourceExtensions; + protected AbstractProcessor(String[] sourceExtensions, + String[] headerExtensions) { + this.sourceExtensions = (String[]) sourceExtensions.clone(); + this.headerExtensions = (String[]) headerExtensions.clone(); + } + /** + * Returns the bid of the processor for the file. + * + * @param inputFile + * filename of input file + * @return bid for the file, 0 indicates no interest, 1 indicates that the + * processor recognizes the file but doesn't process it (header + * files, for example), 100 indicates strong interest + */ + public int bid(String inputFile) { + String lower = inputFile.toLowerCase(); + for (int i = 0; i < sourceExtensions.length; i++) { + if (lower.endsWith(sourceExtensions[i])) { + return DEFAULT_PROCESS_BID; + } + } + for (int i = 0; i < headerExtensions.length; i++) { + if (lower.endsWith(headerExtensions[i])) { + return DEFAULT_DISCARD_BID; + } + } + return 0; + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + return this; + } + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + public String[] getHeaderExtensions() { + return (String[]) this.headerExtensions.clone(); + } + abstract public String getIdentifier(); + /** + * Gets the target operating system architecture + * + * @return String target operating system architecture + */ + protected String getOSArch() { + return System.getProperty("os.arch"); + } + /** + * Gets the target operating system name + * + * @return String target operating system name + */ + protected String getOSName() { + return System.getProperty("os.name"); + } + public String[] getSourceExtensions() { + return (String[]) this.sourceExtensions.clone(); + } + /** + * Returns true if the target operating system is Mac OS X or Darwin. + * + * @return boolean + */ + protected boolean isDarwin() { + String osName = getOSName(); + return "Mac OS X".equals(osName); + } + public final String toString() { + return getIdentifier(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java new file mode 100644 index 0000000..83c59f7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java @@ -0,0 +1,122 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.Vector; + +import org.apache.tools.ant.taskdefs.Execute; +import org.apache.tools.ant.taskdefs.ExecuteStreamHandler; +/** + * Implements ExecuteStreamHandler to capture the output of a Execute to an + * array of strings + * + * @author Curt Arnold + */ +public class CaptureStreamHandler implements ExecuteStreamHandler { + /** + * Runs an executable and captures the output in a String array + * + * @param cmdline + * command line arguments + * @return output of process + */ + public static String[] run(String[] cmdline) { + CaptureStreamHandler handler = new CaptureStreamHandler(); + Execute exec = new Execute(handler); + exec.setCommandline(cmdline); + try { + int status = exec.execute(); + } catch (IOException ex) { + } + return handler.getOutput(); + } + private InputStream errorStream; + private InputStream fromProcess; + public CaptureStreamHandler() { + } + public String[] getOutput() { + String[] output; + if (fromProcess != null) { + Vector lines = new Vector(10); + try { + BufferedReader reader = new BufferedReader( + new InputStreamReader(errorStream)); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 100; j++) { + String line = reader.readLine(); + if (line == null) { + reader = new BufferedReader(new InputStreamReader( + fromProcess)); + break; + } + lines.addElement(line); + } + } + } catch (IOException ex) { + } + output = new String[lines.size()]; + lines.copyInto(output); + return output; + } + output = new String[0]; + return output; + } + /** + * Install a handler for the error stream of the subprocess. + * + * @param is + * input stream to read from the error stream from the + * subprocess + */ + public void setProcessErrorStream(InputStream is) throws IOException { + errorStream = is; + } + /** + * Install a handler for the input stream of the subprocess. + * + * @param os + * output stream to write to the standard input stream of the + * subprocess + */ + public void setProcessInputStream(OutputStream os) throws IOException { + os.close(); + } + /** + * Install a handler for the output stream of the subprocess. + * + * @param is + * input stream to read from the error stream from the + * subprocess + */ + public void setProcessOutputStream(InputStream is) throws IOException { + fromProcess = is; + } + /** + * Start handling of the streams. + */ + public void start() throws IOException { + } + /** + * Stop handling of the streams - will not be restarted. + */ + public void stop() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java new file mode 100644 index 0000000..adafa08 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java @@ -0,0 +1,42 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.types.Environment; +/** + * An abstract Compiler implementation which uses an external program to + * perform the compile. + * + * @author Adam Murdoch + */ +public abstract class CommandLineCCompiler extends CommandLineCompiler { + protected CommandLineCCompiler(String command, String identifierArg, + String[] sourceExtensions, String[] headerExtensions, + String outputSuffix, boolean libtool, + CommandLineCCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super(command, identifierArg, sourceExtensions, headerExtensions, + outputSuffix, libtool, libtoolCompiler, newEnvironment, env); + } + protected Parser createParser(File source) { + return new CParser(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java new file mode 100644 index 0000000..46ec59a --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java @@ -0,0 +1,437 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.CompilerDef; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.ProcessorParam; +import net.sf.antcontrib.cpptasks.types.CommandLineArgument; +import net.sf.antcontrib.cpptasks.types.UndefineArgument; +import net.sf.antcontrib.cpptasks.TargetDef; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum;; +/** + * An abstract Compiler implementation which uses an external program to + * perform the compile. + * + * @author Adam Murdoch + */ +public abstract class CommandLineCompiler extends AbstractCompiler { + private String command; + private final Environment env; + private String identifier; + private String identifierArg; + private boolean libtool; + private CommandLineCompiler libtoolCompiler; + private final boolean newEnvironment; + protected CommandLineCompiler(String command, String identifierArg, + String[] sourceExtensions, String[] headerExtensions, + String outputSuffix, boolean libtool, + CommandLineCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super(sourceExtensions, headerExtensions, outputSuffix); + this.command = command; + if (libtool && libtoolCompiler != null) { + throw new java.lang.IllegalArgumentException( + "libtoolCompiler should be null when libtool is true"); + } + this.libtool = libtool; + this.libtoolCompiler = libtoolCompiler; + this.identifierArg = identifierArg; + this.newEnvironment = newEnvironment; + this.env = env; + } + abstract protected void addImpliedArgs(Vector args, boolean debug, + boolean multithreaded, boolean exceptions, LinkType linkType, + Boolean rtti, OptimizationEnum optimization); + /** + * Adds command-line arguments for include directories. + * + * If relativeArgs is not null will add corresponding relative paths + * include switches to that vector (for use in building a configuration + * identifier that is consistent between machines). + * + * @param baseDirPath Base directory path. + * @param includeDirs + * Array of include directory paths + * @param args + * Vector of command line arguments used to execute the task + * @param relativeArgs + * Vector of command line arguments used to build the + * configuration identifier + */ + protected void addIncludes(String baseDirPath, File[] includeDirs, + Vector args, Vector relativeArgs, StringBuffer includePathId) { + for (int i = 0; i < includeDirs.length; i++) { + args.addElement(getIncludeDirSwitch(includeDirs[i] + .getAbsolutePath())); + if (relativeArgs != null) { + String relative = CUtil.getRelativePath(baseDirPath, + includeDirs[i]); + relativeArgs.addElement(getIncludeDirSwitch(relative)); + if (includePathId != null) { + if (includePathId.length() == 0) { + includePathId.append("/I"); + } else { + includePathId.append(" /I"); + } + includePathId.append(relative); + } + } + } + } + abstract protected void addWarningSwitch(Vector args, int warnings); + protected void buildDefineArguments(CompilerDef[] defs, Vector args) { + // + // assume that we aren't inheriting defines from containing + // + UndefineArgument[] merged = defs[0].getActiveDefines(); + for (int i = 1; i < defs.length; i++) { + // + // if we are inheriting, merge the specific defines with the + // containing defines + merged = UndefineArgument.merge(defs[i].getActiveDefines(), merged); + } + StringBuffer buf = new StringBuffer(30); + for (int i = 0; i < merged.length; i++) { + buf.setLength(0); + UndefineArgument current = merged[i]; + if (current.isDefine()) { + getDefineSwitch(buf, current.getName(), current.getValue()); + } else { + getUndefineSwitch(buf, current.getName()); + } + args.addElement(buf.toString()); + } + } + /** + * Compiles a source file. + * + */ + public void compile(CCTask task, File outputDir, String[] sourceFiles, + String[] args, String[] endArgs, boolean relentless, + CommandLineCompilerConfiguration config, ProgressMonitor monitor) + throws BuildException { + BuildException exc = null; + // + // determine length of executable name and args + // + String command = getCommand(); + int baseLength = command.length() + args.length + endArgs.length; + if (libtool) { + baseLength += 8; + } + for (int i = 0; i < args.length; i++) { + baseLength += args[i].length(); + } + for (int i = 0; i < endArgs.length; i++) { + baseLength += endArgs[i].length(); + } + if (baseLength > getMaximumCommandLength()) { + throw new BuildException( + "Command line is over maximum length without specifying source file"); + } + // + // typically either 1 or Integer.MAX_VALUE + // + int maxInputFilesPerCommand = getMaximumInputFilesPerCommand(); + int argumentCountPerInputFile = getArgumentCountPerInputFile(); + for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) { + int cmdLength = baseLength; + int firstFileNextExec; + for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length + && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) { + cmdLength += getTotalArgumentLengthForInputFile(outputDir, + sourceFiles[firstFileNextExec]); + if (cmdLength >= getMaximumCommandLength()) + break; + } + if (firstFileNextExec == sourceIndex) { + throw new BuildException( + "Extremely long file name, can't fit on command line"); + } + int argCount = args.length + 1 + endArgs.length + + (firstFileNextExec - sourceIndex) + * argumentCountPerInputFile; + if (libtool) { + argCount++; + } + String[] commandline = new String[argCount]; + int index = 0; + if (libtool) { + commandline[index++] = "libtool"; + } + commandline[index++] = command; + for (int j = 0; j < args.length; j++) { + commandline[index++] = args[j]; + } + for (int j = sourceIndex; j < firstFileNextExec; j++) { + for (int k = 0; k < argumentCountPerInputFile; k++) { + commandline[index++] = getInputFileArgument(outputDir, + sourceFiles[j], k); + } + } + for (int j = 0; j < endArgs.length; j++) { + commandline[index++] = endArgs[j]; + } + int retval = runCommand(task, outputDir, commandline); + if (monitor != null) { + String[] fileNames = new String[firstFileNextExec - sourceIndex]; + for (int j = 0; j < fileNames.length; j++) { + fileNames[j] = sourceFiles[sourceIndex + j]; + } + monitor.progress(fileNames); + } + // + // if the process returned a failure code and + // we aren't holding an exception from an earlier + // interation + if (retval != 0 && exc == null) { + // + // construct the exception + // + exc = new BuildException(this.getCommand() + + " failed with return code " + retval, task + .getLocation()); + // + // and throw it now unless we are relentless + // + if (!relentless) { + throw exc; + } + } + sourceIndex = firstFileNextExec; + } + // + // if the compiler returned a failure value earlier + // then throw an exception + if (exc != null) { + throw exc; + } + } + protected CompilerConfiguration createConfiguration(final CCTask task, + final LinkType linkType, + final ProcessorDef[] baseDefs, + final CompilerDef specificDef, + final TargetDef targetPlatform, + final VersionInfo versionInfo) { + Vector args = new Vector(); + CompilerDef[] defaultProviders = new CompilerDef[baseDefs.length + 1]; + for (int i = 0; i < baseDefs.length; i++) { + defaultProviders[i + 1] = (CompilerDef) baseDefs[i]; + } + defaultProviders[0] = specificDef; + Vector cmdArgs = new Vector(); + // + // add command line arguments inherited from element + // any "extends" and finally the specific CompilerDef + CommandLineArgument[] commandArgs; + for (int i = defaultProviders.length - 1; i >= 0; i--) { + commandArgs = defaultProviders[i].getActiveProcessorArgs(); + for (int j = 0; j < commandArgs.length; j++) { + if (commandArgs[j].getLocation() == 0) { + args.addElement(commandArgs[j].getValue()); + } else { + cmdArgs.addElement(commandArgs[j]); + } + } + } + Vector params = new Vector(); + // + // add command line arguments inherited from element + // any "extends" and finally the specific CompilerDef + ProcessorParam[] paramArray; + for (int i = defaultProviders.length - 1; i >= 0; i--) { + paramArray = defaultProviders[i].getActiveProcessorParams(); + for (int j = 0; j < paramArray.length; j++) { + params.add(paramArray[j]); + } + } + paramArray = (ProcessorParam[]) (params + .toArray(new ProcessorParam[params.size()])); + boolean multithreaded = specificDef.getMultithreaded(defaultProviders, + 1); + boolean debug = specificDef.getDebug(baseDefs, 0); + boolean exceptions = specificDef.getExceptions(defaultProviders, 1); + Boolean rtti = specificDef.getRtti(defaultProviders, 1); + OptimizationEnum optimization = specificDef.getOptimization(defaultProviders, 1); + this.addImpliedArgs(args, debug, multithreaded, exceptions, linkType, rtti, optimization); + // + // add all appropriate defines and undefines + // + buildDefineArguments(defaultProviders, args); + int warnings = specificDef.getWarnings(defaultProviders, 0); + addWarningSwitch(args, warnings); + Enumeration argEnum = cmdArgs.elements(); + int endCount = 0; + while (argEnum.hasMoreElements()) { + CommandLineArgument arg = (CommandLineArgument) argEnum + .nextElement(); + switch (arg.getLocation()) { + case 1 : + args.addElement(arg.getValue()); + break; + case 2 : + endCount++; + break; + } + } + String[] endArgs = new String[endCount]; + argEnum = cmdArgs.elements(); + int index = 0; + while (argEnum.hasMoreElements()) { + CommandLineArgument arg = (CommandLineArgument) argEnum + .nextElement(); + if (arg.getLocation() == 2) { + endArgs[index++] = arg.getValue(); + } + } + // + // Want to have distinct set of arguments with relative + // path names for includes that are used to build + // the configuration identifier + // + Vector relativeArgs = (Vector) args.clone(); + // + // add all active include and sysincludes + // + StringBuffer includePathIdentifier = new StringBuffer(); + File baseDir = specificDef.getProject().getBaseDir(); + String baseDirPath; + try { + baseDirPath = baseDir.getCanonicalPath(); + } catch (IOException ex) { + baseDirPath = baseDir.toString(); + } + Vector includePath = new Vector(); + Vector sysIncludePath = new Vector(); + for (int i = defaultProviders.length - 1; i >= 0; i--) { + String[] incPath = defaultProviders[i].getActiveIncludePaths(); + for (int j = 0; j < incPath.length; j++) { + includePath.addElement(incPath[j]); + } + incPath = defaultProviders[i].getActiveSysIncludePaths(); + for (int j = 0; j < incPath.length; j++) { + sysIncludePath.addElement(incPath[j]); + } + } + File[] incPath = new File[includePath.size()]; + for (int i = 0; i < includePath.size(); i++) { + incPath[i] = new File((String) includePath.elementAt(i)); + } + File[] sysIncPath = new File[sysIncludePath.size()]; + for (int i = 0; i < sysIncludePath.size(); i++) { + sysIncPath[i] = new File((String) sysIncludePath.elementAt(i)); + } + addIncludes(baseDirPath, incPath, args, relativeArgs, + includePathIdentifier); + addIncludes(baseDirPath, sysIncPath, args, null, null); + StringBuffer buf = new StringBuffer(getIdentifier()); + for (int i = 0; i < relativeArgs.size(); i++) { + buf.append(' '); + buf.append(relativeArgs.elementAt(i)); + } + for (int i = 0; i < endArgs.length; i++) { + buf.append(' '); + buf.append(endArgs[i]); + } + String configId = buf.toString(); + String[] argArray = new String[args.size()]; + args.copyInto(argArray); + boolean rebuild = specificDef.getRebuild(baseDefs, 0); + File[] envIncludePath = getEnvironmentIncludePath(); + return new CommandLineCompilerConfiguration(this, configId, incPath, + sysIncPath, envIncludePath, includePathIdentifier.toString(), + argArray, paramArray, rebuild, endArgs); + } + protected int getArgumentCountPerInputFile() { + return 1; + } + protected final String getCommand() { + return command; + } + abstract protected void getDefineSwitch(StringBuffer buffer, String define, + String value); + protected abstract File[] getEnvironmentIncludePath(); + public String getIdentifier() { + if (identifier == null) { + if (identifierArg == null) { + identifier = getIdentifier(new String[]{command}, command); + } else { + identifier = getIdentifier( + new String[]{command, identifierArg}, command); + } + } + return identifier; + } + abstract protected String getIncludeDirSwitch(String source); + protected String getInputFileArgument(File outputDir, String filename, + int index) { + // + // if there is an embedded space, + // must enclose in quotes + if (filename.indexOf(' ') >= 0) { + StringBuffer buf = new StringBuffer("\""); + buf.append(filename); + buf.append("\""); + return buf.toString(); + } + return filename; + } + protected final boolean getLibtool() { + return libtool; + } + /** + * Obtains the same compiler, but with libtool set + * + * Default behavior is to ignore libtool + */ + public final CommandLineCompiler getLibtoolCompiler() { + if (libtoolCompiler != null) { + return libtoolCompiler; + } + return this; + } + abstract public int getMaximumCommandLength(); + protected int getMaximumInputFilesPerCommand() { + return Integer.MAX_VALUE; + } + protected int getTotalArgumentLengthForInputFile(File outputDir, + String inputFile) { + return inputFile.length() + 1; + } + abstract protected void getUndefineSwitch(StringBuffer buffer, String define); + /** + * This method is exposed so test classes can overload and test the + * arguments without actually spawning the compiler + */ + protected int runCommand(CCTask task, File workingDir, String[] cmdline) + throws BuildException { + return CUtil.runCommand(task, workingDir, cmdline, newEnvironment, env); + } + protected final void setCommand(String command) { + this.command = command; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java new file mode 100644 index 0000000..38492ea --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java @@ -0,0 +1,226 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CompilerParam; +import net.sf.antcontrib.cpptasks.DependencyInfo; +import net.sf.antcontrib.cpptasks.ProcessorParam; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +/** + * A configuration for a C++ compiler + * + * @author Curt Arnold + */ +public final class CommandLineCompilerConfiguration + implements + CompilerConfiguration { + private/* final */String[] args; + private/* final */CommandLineCompiler compiler; + private String[] endArgs; + // + // include path from environment variable not + // explicitly stated in Ant script + private/* final */File[] envIncludePath; + private String[] exceptFiles; + private/* final */String identifier; + private/* final */File[] includePath; + private/* final */String includePathIdentifier; + private boolean isPrecompiledHeaderGeneration; + private/* final */ProcessorParam[] params; + private/* final */boolean rebuild; + private/* final */File[] sysIncludePath; + public CommandLineCompilerConfiguration(CommandLineCompiler compiler, + String identifier, File[] includePath, File[] sysIncludePath, + File[] envIncludePath, String includePathIdentifier, String[] args, + ProcessorParam[] params, boolean rebuild, String[] endArgs) { + if (compiler == null) { + throw new NullPointerException("compiler"); + } + if (identifier == null) { + throw new NullPointerException("identifier"); + } + if (includePathIdentifier == null) { + throw new NullPointerException("includePathIdentifier"); + } + if (args == null) { + this.args = new String[0]; + } else { + this.args = (String[]) args.clone(); + } + if (includePath == null) { + this.includePath = new File[0]; + } else { + this.includePath = (File[]) includePath.clone(); + } + if (sysIncludePath == null) { + this.sysIncludePath = new File[0]; + } else { + this.sysIncludePath = (File[]) sysIncludePath.clone(); + } + if (envIncludePath == null) { + this.envIncludePath = new File[0]; + } else { + this.envIncludePath = (File[]) envIncludePath.clone(); + } + this.compiler = compiler; + this.params = (ProcessorParam[]) params.clone(); + this.rebuild = rebuild; + this.identifier = identifier; + this.includePathIdentifier = includePathIdentifier; + this.endArgs = (String[]) endArgs.clone(); + exceptFiles = null; + isPrecompiledHeaderGeneration = false; + } + public CommandLineCompilerConfiguration( + CommandLineCompilerConfiguration base, String[] additionalArgs, + String[] exceptFiles, boolean isPrecompileHeaderGeneration) { + compiler = base.compiler; + identifier = base.identifier; + rebuild = base.rebuild; + includePath = (File[]) base.includePath.clone(); + sysIncludePath = (File[]) base.sysIncludePath.clone(); + endArgs = (String[]) base.endArgs.clone(); + envIncludePath = (File[]) base.envIncludePath.clone(); + includePathIdentifier = base.includePathIdentifier; + if (exceptFiles != null) { + this.exceptFiles = (String[]) exceptFiles.clone(); + } + this.isPrecompiledHeaderGeneration = isPrecompileHeaderGeneration; + args = new String[base.args.length + additionalArgs.length]; + for (int i = 0; i < base.args.length; i++) { + args[i] = base.args[i]; + } + int index = base.args.length; + for (int i = 0; i < additionalArgs.length; i++) { + args[index++] = additionalArgs[i]; + } + } + public int bid(String inputFile) { + int compilerBid = compiler.bid(inputFile); + if (compilerBid > 0 && exceptFiles != null) { + for (int i = 0; i < exceptFiles.length; i++) { + if (inputFile.equals(exceptFiles[i])) { + return 0; + } + } + } + return compilerBid; + } + public void compile(CCTask task, File outputDir, String[] sourceFiles, + boolean relentless, ProgressMonitor monitor) throws BuildException { + if (monitor != null) { + monitor.start(this); + } + try { + compiler.compile(task, outputDir, sourceFiles, args, endArgs, + relentless, this, monitor); + if (monitor != null) { + monitor.finish(this, true); + } + } catch (BuildException ex) { + if (monitor != null) { + monitor.finish(this, false); + } + throw ex; + } + } + /** + * + * This method may be used to get two distinct compiler configurations, one + * for compiling the specified file and producing a precompiled header + * file, and a second for compiling other files using the precompiled + * header file. + * + * The last (preferrably only) include directive in the prototype file will + * be used to mark the boundary between pre-compiled and normally compiled + * headers. + * + * @param prototype + * A source file (for example, stdafx.cpp) that is used to build + * the precompiled header file. @returns null if precompiled + * headers are not supported or a two element array containing + * the precompiled header generation configuration and the + * consuming configuration + * + */ + public CompilerConfiguration[] createPrecompileConfigurations( + File prototype, String[] nonPrecompiledFiles) { + if (compiler instanceof PrecompilingCompiler) { + return ((PrecompilingCompiler) compiler) + .createPrecompileConfigurations(this, prototype, + nonPrecompiledFiles); + } + return null; + } + /** + * Returns a string representation of this configuration. Should be + * canonical so that equivalent configurations will have equivalent string + * representations + */ + public String getIdentifier() { + return identifier; + } + public String getIncludePathIdentifier() { + return includePathIdentifier; + } + public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) { + return compiler.getOutputFileNames(inputFile, versionInfo); + } + public CompilerParam getParam(String name) { + for (int i = 0; i < params.length; i++) { + if (name.equals(params[i].getName())) + return (CompilerParam) params[i]; + } + return null; + } + public ProcessorParam[] getParams() { + return params; + } + public boolean getRebuild() { + return rebuild; + } + public boolean isPrecompileGeneration() { + return isPrecompiledHeaderGeneration; + } + public DependencyInfo parseIncludes(CCTask task, File baseDir, File source) { + return compiler.parseIncludes(task, source, includePath, + sysIncludePath, envIncludePath, baseDir, + getIncludePathIdentifier()); + } + public String toString() { + return identifier; + } + public String[] getPreArguments() { + return (String[]) args.clone(); + } + public String[] getEndArguments() { + return (String[]) endArgs.clone(); + } + public File[] getIncludePath() { + return (File[]) includePath.clone(); + } + public Compiler getCompiler() { + return compiler; + } + public String getCommand() { + return compiler.getCommand(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java new file mode 100644 index 0000000..7b0eed2 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java @@ -0,0 +1,42 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.parser.FortranParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.types.Environment; +/** + * An abstract Compiler implementation which uses an external program to + * perform the compile. + * + * @author Curt Arnold + */ +public abstract class CommandLineFortranCompiler extends CommandLineCompiler { + protected CommandLineFortranCompiler(String command, String identifierArg, + String[] sourceExtensions, String[] headerExtensions, + String outputSuffix, boolean libtool, + CommandLineFortranCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super(command, identifierArg, sourceExtensions, headerExtensions, + outputSuffix, libtool, libtoolCompiler, newEnvironment, env); + } + protected Parser createParser(File source) { + return new FortranParser(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java new file mode 100644 index 0000000..86594fa --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java @@ -0,0 +1,407 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.LinkerDef; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.ProcessorParam; +import net.sf.antcontrib.cpptasks.types.CommandLineArgument; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.TargetDef; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; + + +/** + * An abstract Linker implementation that performs the link via an external + * command. + * + * @author Adam Murdoch + */ +public abstract class CommandLineLinker extends AbstractLinker +{ + private String command; + private Environment env = null; + private String identifier; + private String identifierArg; + private boolean isLibtool; + private String[] librarySets; + private CommandLineLinker libtoolLinker; + private boolean newEnvironment = false; + private String outputSuffix; + + + /** Creates a comand line linker invocation */ + public CommandLineLinker(String command, + String identifierArg, + String[] extensions, + String[] ignoredExtensions, String outputSuffix, + boolean isLibtool, CommandLineLinker libtoolLinker) + { + super(extensions, ignoredExtensions); + this.command = command; + this.identifierArg = identifierArg; + this.outputSuffix = outputSuffix; + this.isLibtool = isLibtool; + this.libtoolLinker = libtoolLinker; + } + protected abstract void addBase(long base, Vector args); + + protected abstract void addFixed(Boolean fixed, Vector args); + + abstract protected void addImpliedArgs(boolean debug, + LinkType linkType, Vector args); + protected abstract void addIncremental(boolean incremental, Vector args); + + // + // Windows processors handle these through file list + // + protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, Vector preargs, + Vector midargs, Vector endargs) { + return null; + } + protected abstract void addMap(boolean map, Vector args); + protected abstract void addStack(int stack, Vector args); + protected abstract void addEntry(String entry, Vector args); + + protected LinkerConfiguration createConfiguration( + CCTask task, + LinkType linkType, + ProcessorDef[] baseDefs, LinkerDef specificDef, TargetDef targetPlatform, + VersionInfo versionInfo) { + + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + Vector[] args = new Vector[] { preargs, midargs, endargs }; + + LinkerDef[] defaultProviders = new LinkerDef[baseDefs.length+1]; + defaultProviders[0] = specificDef; + for(int i = 0; i < baseDefs.length; i++) { + defaultProviders[i+1] = (LinkerDef) baseDefs[i]; + } + // + // add command line arguments inherited from element + // any "extends" and finally the specific CompilerDef + CommandLineArgument[] commandArgs; + for(int i = defaultProviders.length-1; i >= 0; i--) { + commandArgs = defaultProviders[i].getActiveProcessorArgs(); + for(int j = 0; j < commandArgs.length; j++) { + args[commandArgs[j].getLocation()]. + addElement(commandArgs[j].getValue()); + } + } + + Vector params = new Vector(); + // + // add command line arguments inherited from element + // any "extends" and finally the specific CompilerDef + ProcessorParam[] paramArray; + for (int i = defaultProviders.length - 1; i >= 0; i--) { + paramArray = defaultProviders[i].getActiveProcessorParams(); + for (int j = 0; j < paramArray.length; j++) { + params.add(paramArray[j]); + } + } + + paramArray = (ProcessorParam[])(params.toArray(new ProcessorParam[params.size()])); + + boolean debug = specificDef.getDebug(baseDefs,0); + + + String startupObject = getStartupObject(linkType); + + addImpliedArgs(debug, linkType, preargs); + addIncremental(specificDef.getIncremental(defaultProviders,1), preargs); + addFixed(specificDef.getFixed(defaultProviders,1), preargs); + addMap(specificDef.getMap(defaultProviders,1), preargs); + addBase(specificDef.getBase(defaultProviders,1), preargs); + addStack(specificDef.getStack(defaultProviders,1), preargs); + addEntry(specificDef.getEntry(defaultProviders, 1), preargs); + + String[] libnames = null; + LibrarySet[] libsets = specificDef.getActiveLibrarySets(defaultProviders,1); + if (libsets.length > 0) { + libnames = addLibrarySets(task, libsets, preargs, midargs, endargs); + } + + StringBuffer buf = new StringBuffer(getIdentifier()); + for (int i = 0; i < 3; i++) { + Enumeration argenum = args[i].elements(); + while (argenum.hasMoreElements()) { + buf.append(' '); + buf.append(argenum.nextElement().toString()); + } + } + String configId = buf.toString(); + + String[][] options = new String[][] { + new String[args[0].size() + args[1].size()], + new String[args[2].size()] }; + args[0].copyInto(options[0]); + int offset = args[0].size(); + for (int i = 0; i < args[1].size(); i++) { + options[0][i+offset] = (String) args[1].elementAt(i); + } + args[2].copyInto(options[1]); + + + boolean rebuild = specificDef.getRebuild(baseDefs,0); + boolean map = specificDef.getMap(defaultProviders,1); + + //task.log("libnames:"+libnames.length, Project.MSG_VERBOSE); + return new CommandLineLinkerConfiguration(this,configId,options, + paramArray, + rebuild,map, debug,libnames, startupObject); + } + + /** + * Allows drived linker to decorate linker option. + * Override by GccLinker to prepend a "-Wl," to + * pass option to through gcc to linker. + * + * @param buf buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg linker argument + */ + protected String decorateLinkerOption(StringBuffer buf, String arg) { + return arg; + } + + protected final String getCommand() { + return command; + } + protected abstract String getCommandFileSwitch(String commandFile); + + + public String getIdentifier() { + if(identifier == null) { + if (identifierArg == null) { + identifier = getIdentifier(new String[] { command }, command); + } else { + identifier = getIdentifier(new String[] { command, identifierArg }, + command); + } + } + return identifier; + } + public final CommandLineLinker getLibtoolLinker() { + if (libtoolLinker != null) { + return libtoolLinker; + } + return this; + } + protected abstract int getMaximumCommandLength(); + + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + return new String[] { baseName + outputSuffix }; + } + + protected String[] getOutputFileSwitch(CCTask task, String outputFile) { + return getOutputFileSwitch(outputFile); + } + protected abstract String[] getOutputFileSwitch(String outputFile); + protected String getStartupObject(LinkType linkType) { + return null; + } + + /** + * Performs a link using a command line linker + * + */ + public void link(CCTask task, + File outputFile, + String[] sourceFiles, + CommandLineLinkerConfiguration config) + throws BuildException + { + File parentDir = new File(outputFile.getParent()); + String parentPath; + try { + parentPath = parentDir.getCanonicalPath(); + } catch(IOException ex) { + parentPath = parentDir.getAbsolutePath(); + } + String[] execArgs = prepareArguments(task, parentPath,outputFile.getName(), + sourceFiles, config); + int commandLength = 0; + for(int i = 0; i < execArgs.length; i++) { + commandLength += execArgs[i].length() + 1; + } + + // + // if command length exceeds maximum + // then create a temporary + // file containing everything but the command name + if(commandLength >= this.getMaximumCommandLength()) { + try { + execArgs = prepareResponseFile(outputFile,execArgs); + } + catch(IOException ex) { + throw new BuildException(ex); + } + } + + int retval = runCommand(task,parentDir,execArgs); + // + // if the process returned a failure code then + // throw an BuildException + // + if(retval != 0) { + // + // construct the exception + // + throw new BuildException(this.getCommand() + " failed with return code " + retval, task.getLocation()); + } + + } + + + /** + * Prepares argument list for exec command. Will return null + * if command line would exceed allowable command line buffer. + * + * @param task compilation task. + * @param outputFile linker output file + * @param sourceFiles linker input files (.obj, .o, .res) + * @param config linker configuration + * @return arguments for runTask + */ + protected String[] prepareArguments( + CCTask task, + String outputDir, + String outputFile, + String[] sourceFiles, + CommandLineLinkerConfiguration config) { + + String[] preargs = config.getPreArguments(); + String[] endargs = config.getEndArguments(); + String outputSwitch[] = getOutputFileSwitch(task, outputFile); + int allArgsCount = preargs.length + 1 + outputSwitch.length + + sourceFiles.length + endargs.length; + if (isLibtool) { + allArgsCount++; + } + String[] allArgs = new String[allArgsCount]; + int index = 0; + if (isLibtool) { + allArgs[index++] = "libtool"; + } + allArgs[index++] = this.getCommand(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < preargs.length; i++) { + allArgs[index++] = decorateLinkerOption(buf, preargs[i]); + } + for (int i = 0; i < outputSwitch.length; i++) { + allArgs[index++] = outputSwitch[i]; + } + for (int i = 0; i < sourceFiles.length; i++) { + allArgs[index++] = prepareFilename(buf,outputDir,sourceFiles[i]); + } + for (int i = 0; i < endargs.length; i++) { + allArgs[index++] = decorateLinkerOption(buf, endargs[i]); + } + return allArgs; + } + + /** + * Processes filename into argument form + * + */ + protected String prepareFilename(StringBuffer buf, + String outputDir, String sourceFile) { + String relativePath = CUtil.getRelativePath(outputDir, + new File(sourceFile)); + return quoteFilename(buf,relativePath); + } + + /** + * Prepares argument list to execute the linker using a + * response file. + * + * @param outputFile linker output file + * @param args output of prepareArguments + * @return arguments for runTask + */ + protected String[] prepareResponseFile(File outputFile,String[] args) throws IOException + { + String baseName = outputFile.getName(); + File commandFile = new File(outputFile.getParent(),baseName + ".rsp"); + FileWriter writer = new FileWriter(commandFile); + int execArgCount = 1; + if (isLibtool) { + execArgCount++; + } + String[] execArgs = new String[execArgCount+1]; + for (int i = 0; i < execArgCount; i++) { + execArgs[i] = args[i]; + } + execArgs[execArgCount] = getCommandFileSwitch(commandFile.toString()); + for(int i = execArgCount; i < args.length; i++) { + // + // if embedded space and not quoted then + // quote argument + if (args[i].indexOf(" ") >= 0 && args[i].charAt(0) != '\"') { + writer.write('\"'); + writer.write(args[i]); + writer.write("\"\n"); + } else { + writer.write(args[i]); + writer.write('\n'); + } + } + writer.close(); + return execArgs; + } + + + protected String quoteFilename(StringBuffer buf,String filename) { + if(filename.indexOf(' ') >= 0) { + buf.setLength(0); + buf.append('\"'); + buf.append(filename); + buf.append('\"'); + return buf.toString(); + } + return filename; + } + + /** + * This method is exposed so test classes can overload + * and test the arguments without actually spawning the + * compiler + */ + protected int runCommand(CCTask task, File workingDir,String[] cmdline) + throws BuildException { + return CUtil.runCommand(task,workingDir,cmdline, newEnvironment, env); + } + + protected final void setCommand(String command) { + this.command = command; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java new file mode 100644 index 0000000..f0aad67 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java @@ -0,0 +1,128 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.LinkerParam; +import net.sf.antcontrib.cpptasks.ProcessorParam; +import net.sf.antcontrib.cpptasks.TargetInfo; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +/** + * A configuration for a command line linker + * + * @author Curt Arnold + */ +public final class CommandLineLinkerConfiguration + implements + LinkerConfiguration { + private/* final */String[][] args; + private/* final */String identifier; + private String[] libraryNames; + private/* final */CommandLineLinker linker; + private/* final */boolean map; + private/* final */ProcessorParam[] params; + private/* final */boolean rebuild; + private boolean debug; + private String startupObject; + public CommandLineLinkerConfiguration(CommandLineLinker linker, + String identifier, String[][] args, ProcessorParam[] params, + boolean rebuild, boolean map, boolean debug, String[] libraryNames, + String startupObject) { + if (linker == null) { + throw new NullPointerException("linker"); + } + if (args == null) { + throw new NullPointerException("args"); + } else { + this.args = (String[][]) args.clone(); + } + this.linker = linker; + this.params = (ProcessorParam[]) params.clone(); + this.rebuild = rebuild; + this.identifier = identifier; + this.map = map; + this.debug = debug; + if (libraryNames == null) { + this.libraryNames = new String[0]; + } else { + this.libraryNames = (String[]) libraryNames.clone(); + } + this.startupObject = startupObject; + } + public int bid(String filename) { + return linker.bid(filename); + } + public String[] getEndArguments() { + String[] clone = (String[]) args[1].clone(); + return clone; + } + /** + * Returns a string representation of this configuration. Should be + * canonical so that equivalent configurations will have equivalent string + * representations + */ + public String getIdentifier() { + return identifier; + } + public String[] getLibraryNames() { + String[] clone = (String[]) libraryNames.clone(); + return clone; + } + public boolean getMap() { + return map; + } + public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) { + return linker.getOutputFileNames(inputFile, versionInfo); + } + public LinkerParam getParam(String name) { + for (int i = 0; i < params.length; i++) { + if (name.equals(params[i].getName())) + return (LinkerParam) params[i]; + } + return null; + } + public ProcessorParam[] getParams() { + return params; + } + public String[] getPreArguments() { + String[] clone = (String[]) args[0].clone(); + return clone; + } + public boolean getRebuild() { + return rebuild; + } + public String getStartupObject() { + return startupObject; + } + public void link(CCTask task, TargetInfo linkTarget) throws BuildException { + // + // AllSourcePath's include any syslibsets + // + String[] sourcePaths = linkTarget.getAllSourcePaths(); + linker.link(task, linkTarget.getOutput(), sourcePaths, this); + } + public String toString() { + return identifier; + } + public Linker getLinker() { + return linker; + } + public boolean isDebug() { + return debug; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java new file mode 100644 index 0000000..48bc190 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Compiler.java @@ -0,0 +1,24 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +/** + * A compiler. + * + * @author Adam Murdoch + */ +public interface Compiler extends Processor { +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java new file mode 100644 index 0000000..6aba345 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java @@ -0,0 +1,64 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CompilerParam; +import net.sf.antcontrib.cpptasks.DependencyInfo; + +import org.apache.tools.ant.BuildException; +/** + * A configuration for a compiler + * + * @author Curt Arnold + */ +public interface CompilerConfiguration extends ProcessorConfiguration { + void compile(CCTask task, File outputDir, String[] sourceFiles, + boolean relentless, ProgressMonitor monitor) throws BuildException; + /** + * + * This method may be used to get two distinct compiler configurations, one + * for compiling the specified file and producing a precompiled header + * file, and a second for compiling other files using the precompiled + * header file. + * + * The last (preferrably only) include directive in the prototype file will + * be used to mark the boundary between pre-compiled and normally compiled + * headers. + * + * @param prototype + * A source file (for example, stdafx.cpp) that is used to build + * the precompiled header file. @returns null if precompiled + * headers are not supported or a two element array containing + * the precompiled header generation configuration and the + * consuming configuration + * + */ + CompilerConfiguration[] createPrecompileConfigurations(File prototype, + String[] nonPrecompiledFiles); + /** + * Returns an digest for the include path for the configuration. + * + * This is used to determine if cached dependency information is invalid + * because the include paths have changed + */ + String getIncludePathIdentifier(); + public CompilerParam getParam(String name); + boolean isPrecompileGeneration(); + DependencyInfo parseIncludes(CCTask task, File baseDir, File source); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java new file mode 100644 index 0000000..70ee93f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java @@ -0,0 +1,150 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import net.sf.antcontrib.cpptasks.OutputTypeEnum; +import net.sf.antcontrib.cpptasks.SubsystemEnum; +/** + * This class represents the target platform for the compile and link step. The + * name is an anachronism and should be changed. + * + * @author Curt Arnold + */ +public class LinkType { + private OutputTypeEnum outputType = new OutputTypeEnum(); + private boolean staticRuntime = false; + private SubsystemEnum subsystem = new SubsystemEnum(); + /** + * Constructor + * + * By default, an gui executable with a dynamically linked runtime + * + */ + public LinkType() { + } + /** + * Gets whether the link should produce an executable + * + * @return boolean + */ + public boolean isExecutable() { + String value = outputType.getValue(); + return value.equals("executable"); + } + /** + * Gets whether the link should produce a plugin module. + * + * @return boolean + */ + public boolean isPluginModule() { + String value = outputType.getValue(); + return value.equals("plugin"); + } + /** + * Gets whether the link should produce a shared library. + * + * @return boolean + */ + public boolean isSharedLibrary() { + String value = outputType.getValue(); + return value.equals("shared") || value.equals("plugin"); + } + /** + * Gets whether the link should produce a static library. + * + * @return boolean + */ + public boolean isStaticLibrary() { + String value = outputType.getValue(); + return value.equals("static"); + } + /** + * Gets whether the module should use a statically linked runtime library. + * + * @return boolean + */ + public boolean isStaticRuntime() { + return staticRuntime; + } + /** + * Gets whether the link should produce a module for a console subsystem. + * + * @return boolean + */ + public boolean isSubsystemConsole() { + String value = subsystem.getValue(); + return value.equals("console"); + } + /** + * Gets whether the link should produce a module for a graphical user + * interface subsystem. + * + * @return boolean + */ + public boolean isSubsystemGUI() { + String value = subsystem.getValue(); + return value.equals("gui"); + } + /** + * Sets the output type (execuable, shared, etc). + * + * @param outputType may not be null + */ + public void setOutputType(OutputTypeEnum outputType) { + if (outputType == null) { + throw new IllegalArgumentException("outputType"); + } + this.outputType = outputType; + } + + /** + * Gets the output type. + * @return output type + */ + public String getOutputType() { + return outputType.getValue(); + } + + /** + * Requests use of a static runtime library. + * + * @param staticRuntime + * if true, use static runtime library if possible. + */ + public void setStaticRuntime(boolean staticRuntime) { + this.staticRuntime = staticRuntime; + } + /** + * Sets the subsystem (gui, console, etc). + * + * @param subsystem + * subsystem, may not be null + */ + public void setSubsystem(SubsystemEnum subsystem) { + if (subsystem == null) { + throw new IllegalArgumentException("subsystem"); + } + this.subsystem = subsystem; + } + + /** + * Get subsystem name. + * @return subsystem name + */ + public String getSubsystem() { + return subsystem.getValue(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java new file mode 100644 index 0000000..0638a70 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Linker.java @@ -0,0 +1,80 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; +import java.io.IOException; + +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * A linker for executables, and static and dynamic libraries. + * + * @author Adam Murdoch + */ +public interface Linker extends Processor { + /** + * Extracts the significant part of a library name to ensure there aren't + * collisions + */ + String getLibraryKey(File libname); + /** + * returns the library path for the linker + */ + File[] getLibraryPath(); + /** + * Returns a set of filename patterns corresponding to library names. + * + * For example, "advapi32" would be expanded to "advapi32.dll" by + * DevStudioLinker and to "libadvapi32.a" and "libadvapi32.so" by + * GccLinker. + * + * @param libnames + * array of library names + */ + String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libraryType); + /** + * Gets the linker for the specified link type. + * + * @return appropriate linker or null, will return this if this linker can + * handle the specified link type + */ + Linker getLinker(LinkType linkType); + /** + * Returns true if the linker is case-sensitive + */ + boolean isCaseSensitive(); + + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + */ + void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) throws IOException; +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java new file mode 100644 index 0000000..ff7ac5d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java @@ -0,0 +1,33 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.LinkerParam; +import net.sf.antcontrib.cpptasks.TargetInfo; + +import org.apache.tools.ant.BuildException; +/** + * A configuration for a linker + * + * @author Curt Arnold + */ +public interface LinkerConfiguration extends ProcessorConfiguration { + public LinkerParam getParam(String name); + void link(CCTask task, TargetInfo linkTarget) throws BuildException; + Linker getLinker(); + boolean isDebug(); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java new file mode 100644 index 0000000..2af1a68 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java @@ -0,0 +1,43 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.types.Environment; +/** + * A command line C compiler that can utilize precompilation of header files + * + * @author Curt Arnold + */ +public abstract class PrecompilingCommandLineCCompiler + extends + PrecompilingCommandLineCompiler { + protected PrecompilingCommandLineCCompiler(String command, + String identifierArg, String[] sourceExtensions, + String[] headerExtensions, String outputSuffix, boolean libtool, + PrecompilingCommandLineCCompiler libtoolCompiler, + boolean newEnvironment, Environment env) { + super(command, identifierArg, sourceExtensions, headerExtensions, + outputSuffix, libtool, libtoolCompiler, newEnvironment, env); + } + protected Parser createParser(File source) { + return new CParser(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java new file mode 100644 index 0000000..3b66597 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java @@ -0,0 +1,104 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +/** + * A command line C compiler that can utilize precompilation of header files + * + * @author Curt Arnold + */ +public abstract class PrecompilingCommandLineCompiler + extends + CommandLineCompiler implements PrecompilingCompiler { + protected PrecompilingCommandLineCompiler(String command, + String identifierArg, String[] sourceExtensions, + String[] headerExtensions, String outputSuffix, boolean libtool, + PrecompilingCommandLineCompiler libtoolCompiler, + boolean newEnvironment, Environment env) { + super(command, identifierArg, sourceExtensions, headerExtensions, + outputSuffix, libtool, libtoolCompiler, newEnvironment, env); + } + /** + * + * This method may be used to get two distinct compiler configurations, one + * for compiling the specified file and producing a precompiled header + * file, and a second for compiling other files using the precompiled + * header file. + * + * The last (preferrably only) include directive in the prototype file will + * be used to mark the boundary between pre-compiled and normally compiled + * headers. + * + * @param config + * base configuration + * @param prototype + * A source file (for example, stdafx.cpp) that is used to build + * the precompiled header file. @returns null if precompiled + * headers are not supported or a two element array containing + * the precompiled header generation configuration and the + * consuming configuration + * + */ + public CompilerConfiguration[] createPrecompileConfigurations( + CompilerConfiguration config, File prototype, String[] exceptFiles) { + // + // cast should success or someone is passing us a configuration + // that was prepared by another processor + // + CommandLineCompilerConfiguration cmdLineConfig = (CommandLineCompilerConfiguration) config; + // + // parse prototype file to determine last header + // + Parser parser = createParser(prototype); + String[] includes; + try { + Reader reader = new BufferedReader(new FileReader(prototype)); + parser.parse(reader); + includes = parser.getIncludes(); + } catch (IOException ex) { + throw new BuildException( + "Error parsing precompiled header protoype: " + + prototype.toString() + ":" + ex.toString()); + } + if (includes.length == 0) { + throw new BuildException("Precompiled header prototype: " + + prototype.toString() + + " does not contain any include directives."); + } + CompilerConfiguration[] configs = new CompilerConfiguration[2]; + configs[0] = createPrecompileGeneratingConfig(cmdLineConfig, prototype, + includes[0]); + configs[1] = createPrecompileUsingConfig(cmdLineConfig, prototype, + includes[0], exceptFiles); + return configs; + } + abstract protected CompilerConfiguration createPrecompileGeneratingConfig( + CommandLineCompilerConfiguration baseConfig, File prototype, + String lastInclude); + abstract protected CompilerConfiguration createPrecompileUsingConfig( + CommandLineCompilerConfiguration baseConfig, File prototype, + String lastInclude, String[] exceptFiles); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java new file mode 100644 index 0000000..f707dc5 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java @@ -0,0 +1,49 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; +/** + * A compiler that can utilize precompilation of header files + * + * @author Curt Arnold + */ +public interface PrecompilingCompiler { + /** + * + * This method may be used to get two distinct compiler configurations, one + * for compiling the specified file and producing a precompiled header + * file, and a second for compiling other files using the precompiled + * header file. + * + * The last (preferrably only) include directive in the prototype file will + * be used to mark the boundary between pre-compiled and normally compiled + * headers. + * + * @param config + * base configuration + * @param prototype + * A source file (for example, stdafx.cpp) that is used to build + * the precompiled header file. @returns null if precompiled + * headers are not supported or a two element array containing + * the precompiled header generation configuration and the + * consuming configuration + * + */ + CompilerConfiguration[] createPrecompileConfigurations( + CompilerConfiguration config, File prototype, + String[] nonPrecompiledFiles); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java new file mode 100644 index 0000000..d6513f7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/Processor.java @@ -0,0 +1,75 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.TargetDef; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.types.Environment; +/** + * A processor. Base interface for Compiler and Linker + * + * @author Curt Arnold + */ +public interface Processor { + /** + * Returns a bid indicating the desire of this compiler to process the + * file. + * + * @param inputFile + * input file + * @return 0 = no interest, 100 = high interest + */ + int bid(String inputFile); + Processor changeEnvironment(boolean newEnvironment, Environment env); + /** + * Returns the compiler configuration for or element. + * + * @param defaultProviders + * When specificConfig corresponds to a or linker + * element, defaultProvider will be a zero to two element array. + * If there is an extends attribute, the first element will be + * the referenced ProcessorDef, unless inherit = false, the last + * element will be the containing element + * @param specificConfig + * A or element. + * @return resulting configuration + */ + ProcessorConfiguration createConfiguration(CCTask task, LinkType linkType, + ProcessorDef[] defaultProviders, ProcessorDef specificConfig, + TargetDef targetPlatform, VersionInfo versionInfo); + /** + * Retrieve an identifier that identifies the specific version of the + * compiler. Compilers with the same identifier should produce the same + * output files for the same input files and command line switches. + */ + String getIdentifier(); + /** + * Gets the linker that is associated with this processors + */ + Linker getLinker(LinkType type); + /** + * Output file name (no path components) corresponding to source file + * + * @param inputFile + * input file + * @return output file name or null if no output file or name not + * determined by input file + */ + String[] getOutputFileNames(String inputFile, VersionInfo versionInfo); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java new file mode 100644 index 0000000..870fb33 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java @@ -0,0 +1,54 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import net.sf.antcontrib.cpptasks.ProcessorParam; +import net.sf.antcontrib.cpptasks.VersionInfo; + +/** + * A configuration for a C++ compiler, linker or other processor + * + * @author Curt Arnold + */ +public interface ProcessorConfiguration { + /** + * An indication of how much this compiler would like to process this file + * + * @return 0 is no interest to process, 100 is strong interest to process + */ + int bid(String filename); + /** + * Returns a string representation of this configuration. Should be + * canonical so that equivalent configurations will have equivalent string + * representations + */ + String getIdentifier(); + /** + * Output file name (no path components) corresponding to source file + * + * @param inputFile + * input file + * @return output file names or zero-length array if no output file or name not + * determined by input file + */ + String[] getOutputFileNames(String inputFile, VersionInfo versionInfo); + ProcessorParam[] getParams(); + /** + * If true, all files using this configuration should be rebuilt and any + * existing output files should be ignored + */ + boolean getRebuild(); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java new file mode 100644 index 0000000..9949856 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java @@ -0,0 +1,31 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +/** + * Interface to receive notification of compile progress + * + * @author Curt Arnold + */ +public interface ProgressMonitor { + public void finish(ProcessorConfiguration config, boolean normal); + /** + * Called to notify monitor of progress + * + */ + void progress(String[] sources); + public void start(ProcessorConfiguration config); +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java new file mode 100644 index 0000000..8df73bd --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudio2005CCompiler.java @@ -0,0 +1,62 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; + +import org.apache.tools.ant.types.Environment; + +/** + * Adapter for the Microsoft(r) C/C++ 8 Optimizing Compiler + * + * @author David Haney + */ +public final class DevStudio2005CCompiler extends DevStudioCompatibleCCompiler { + private static final DevStudio2005CCompiler instance = new DevStudio2005CCompiler( + "cl", false, null); + public static DevStudio2005CCompiler getInstance() { + return instance; + } + private DevStudio2005CCompiler(String command, boolean newEnvironment, + Environment env) { + super(command, "/bogus", newEnvironment, env); + } + /** + * Override the default debug flags to use VC 8 compatible versions. + */ + protected void addDebugSwitch(Vector args) { + args.addElement("/Zi"); + args.addElement("/Od"); + args.addElement("/RTC1"); + args.addElement("/D_DEBUG"); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new DevStudio2005CCompiler(getCommand(), newEnvironment, env); + } + return this; + } + public Linker getLinker(LinkType type) { + return DevStudioLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java new file mode 100644 index 0000000..1281046 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java @@ -0,0 +1,50 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Microsoft(r) C/C++ Optimizing Compiler + * + * @author Adam Murdoch + */ +public final class DevStudioCCompiler extends DevStudioCompatibleCCompiler { + private static final DevStudioCCompiler instance = new DevStudioCCompiler( + "cl", false, null); + public static DevStudioCCompiler getInstance() { + return instance; + } + private DevStudioCCompiler(String command, boolean newEnvironment, + Environment env) { + super(command, "/bogus", newEnvironment, env); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new DevStudioCCompiler(getCommand(), newEnvironment, env); + } + return this; + } + public Linker getLinker(LinkType type) { + return DevStudioLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java new file mode 100644 index 0000000..5f37855 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java @@ -0,0 +1,136 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.io.File; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.PrecompilingCommandLineCCompiler; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +/** + * An abstract base class for compilers that are basically command line + * compatible with Microsoft(r) C/C++ Optimizing Compiler + * + * @author Curt Arnold + */ +public abstract class DevStudioCompatibleCCompiler + extends + PrecompilingCommandLineCCompiler { + private static String[] mflags = new String[]{ + // + // first four are single-threaded + // (runtime=static,debug=false), (..,debug=true), + // (runtime=dynamic,debug=true), (..,debug=false), (not supported) + // next four are multi-threaded, same sequence + "/ML", "/MLd", null, null, "/MT", "/MTd", "/MD", "/MDd"}; + protected DevStudioCompatibleCCompiler(String command, + String identifierArg, boolean newEnvironment, Environment env) { + super(command, identifierArg, new String[]{".c", ".cc", ".cpp", ".cxx", + ".c++"}, new String[]{".h", ".hpp", ".inl"}, ".obj", false, + null, newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("/c"); + args.addElement("/nologo"); + if (exceptions) { + // changed to eliminate warning on VC 2005, should support VC 6 and later + // use /GX to support VC5 - 2005 (with warning) + args.addElement("/EHsc"); + } + int mindex = 0; + if (multithreaded) { + mindex += 4; + } + boolean staticRuntime = linkType.isStaticRuntime(); + if (!staticRuntime) { + mindex += 2; + } + if (debug) { + mindex += 1; + addDebugSwitch(args); + } else { + if (optimization != null) { + if (optimization.isSize()) { + args.addElement("/O1"); + } + if (optimization.isSpeed()) { + args.addElement("/O2"); + } + } + args.addElement("/DNDEBUG"); + } + String mflag = mflags[mindex]; + if (mflag == null) { + throw new BuildException( + "multithread='false' and runtime='dynamic' not supported"); + } + args.addElement(mflag); + if (rtti != null && rtti.booleanValue()) { + args.addElement("/GR"); + } + } + protected void addDebugSwitch(Vector args) { + args.addElement("/Zi"); + args.addElement("/Od"); + args.addElement("/GZ"); + args.addElement("/D_DEBUG"); + } + protected void addWarningSwitch(Vector args, int level) { + DevStudioProcessor.addWarningSwitch(args, level); + } + protected CompilerConfiguration createPrecompileGeneratingConfig( + CommandLineCompilerConfiguration baseConfig, File prototype, + String lastInclude) { + String[] additionalArgs = new String[]{ + "/Fp" + CUtil.getBasename(prototype) + ".pch", "/Yc"}; + return new CommandLineCompilerConfiguration(baseConfig, additionalArgs, + null, true); + } + protected CompilerConfiguration createPrecompileUsingConfig( + CommandLineCompilerConfiguration baseConfig, File prototype, + String lastInclude, String[] exceptFiles) { + String[] additionalArgs = new String[]{ + "/Fp" + CUtil.getBasename(prototype) + ".pch", + "/Yu" + lastInclude}; + return new CommandLineCompilerConfiguration(baseConfig, additionalArgs, + exceptFiles, false); + } + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + DevStudioProcessor.getDefineSwitch(buffer, define, value); + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ";"); + } + protected String getIncludeDirSwitch(String includeDir) { + return DevStudioProcessor.getIncludeDirSwitch(includeDir); + } + protected void getUndefineSwitch(StringBuffer buffer, String define) { + DevStudioProcessor.getUndefineSwitch(buffer, define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java new file mode 100644 index 0000000..985dfcf --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java @@ -0,0 +1,80 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +/** + * Abstract base adapter for librarians with command line options compatible + * with the Microsoft(r) Library Manager + * + * @author Curt Arnold + */ +public abstract class DevStudioCompatibleLibrarian extends CommandLineLinker { + public DevStudioCompatibleLibrarian(String command, String identifierArg) { + super(command, identifierArg, new String[]{".obj"}, new String[0], + ".lib", false, null); + } + protected void addBase(long base, Vector args) { + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + args.addElement("/nologo"); + } + protected void addIncremental(boolean incremental, Vector args) { + } + protected void addMap(boolean map, Vector args) { + } + protected void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + protected String getCommandFileSwitch(String cmdFile) { + return "@" + cmdFile; + } + public File[] getLibraryPath() { + return new File[0]; + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return new String[0]; + } + public int getMaximumCommandLength() { + return 32767; + } + public String[] getOutputFileSwitch(String outFile) { + StringBuffer buf = new StringBuffer("/OUT:"); + if (outFile.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(outFile); + buf.append('"'); + } else { + buf.append(outFile); + } + return new String[]{buf.toString()}; + } + public boolean isCaseSensitive() { + return false; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java new file mode 100644 index 0000000..80d2aac --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java @@ -0,0 +1,148 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.io.File; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.platforms.WindowsPlatform; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Abstract base class for linkers that try to mimic the command line arguments + * for the Microsoft (r) Incremental Linker + * + * @author Curt Arnold + */ +public abstract class DevStudioCompatibleLinker extends CommandLineLinker { + public DevStudioCompatibleLinker(String command, String identifierArg, + String outputSuffix) { + super(command, identifierArg, new String[]{".obj", ".lib", ".res"}, + new String[]{".map", ".pdb", ".lnk", ".dll"}, outputSuffix, + false, null); + } + protected void addBase(long base, Vector args) { + if (base >= 0) { + String baseAddr = Long.toHexString(base); + args.addElement("/BASE:0x" + baseAddr); + } + } + protected void addFixed(Boolean fixed, Vector args) { + if (fixed != null) { + if (fixed.booleanValue()) { + args.addElement("/FIXED"); + } else { + args.addElement("/FIXED:NO"); + } + } + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + args.addElement("/NOLOGO"); + if (debug) { + args.addElement("/DEBUG"); + } + if (linkType.isSharedLibrary()) { + args.addElement("/DLL"); + } + // + // The following lines were commented out + // from v 1.5 to v 1.12 with no explanation + // + if(linkType.isSubsystemGUI()) { + args.addElement("/SUBSYSTEM:WINDOWS"); } else { + if(linkType.isSubsystemConsole()) { + args.addElement("/SUBSYSTEM:CONSOLE"); } } + } + protected void addIncremental(boolean incremental, Vector args) { + if (incremental) { + args.addElement("/INCREMENTAL:YES"); + } else { + args.addElement("/INCREMENTAL:NO"); + } + } + protected void addMap(boolean map, Vector args) { + if (map) { + args.addElement("/MAP"); + } + } + protected void addStack(int stack, Vector args) { + if (stack >= 0) { + String stackStr = Integer.toHexString(stack); + args.addElement("/STACK:0x" + stackStr); + } + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + if (entry != null) { + args.addElement("/ENTRY:" + entry); + } + } + + public String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length]; + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(libnames[i]); + buf.append(".lib"); + patterns[i] = buf.toString(); + } + return patterns; + } + public int getMaximumCommandLength() { + return 32767; + } + public String[] getOutputFileSwitch(String outputFile) { + return new String[]{"/OUT:" + outputFile}; + } + public boolean isCaseSensitive() { + return false; + } + + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + */ + public void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) throws IOException { + WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java new file mode 100644 index 0000000..bd63f42 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java @@ -0,0 +1,36 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +/** + * Adapter for the Microsoft (r) Library Manager + * + * @author Curt Arnold + */ +public final class DevStudioLibrarian extends DevStudioCompatibleLibrarian { + private static final DevStudioLibrarian instance = new DevStudioLibrarian(); + public static DevStudioLibrarian getInstance() { + return instance; + } + private DevStudioLibrarian() { + super("lib", "/bogus"); + } + public Linker getLinker(LinkType type) { + return DevStudioLinker.getInstance().getLinker(type); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java new file mode 100644 index 0000000..826074b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java @@ -0,0 +1,44 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +/** + * Adapter for the Microsoft (r) Incremental Linker + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public final class DevStudioLinker extends DevStudioCompatibleLinker { + private static final DevStudioLinker dllLinker = new DevStudioLinker(".dll"); + private static final DevStudioLinker instance = new DevStudioLinker(".exe"); + public static DevStudioLinker getInstance() { + return instance; + } + private DevStudioLinker(String outputSuffix) { + super("link", "/DLL", outputSuffix); + } + public Linker getLinker(LinkType type) { + if (type.isSharedLibrary()) { + return dllLinker; + } + if (type.isStaticLibrary()) { + return DevStudioLibrarian.getInstance(); + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java new file mode 100644 index 0000000..fa2e414 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java @@ -0,0 +1,112 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.io.File; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +/** + * Adapter for the Microsoft (r) MIDL Compiler + * + * @author Curt Arnold + */ +public final class DevStudioMIDLCompiler extends CommandLineCompiler { + private static final DevStudioMIDLCompiler instance = new DevStudioMIDLCompiler( + false, null); + public static DevStudioMIDLCompiler getInstance() { + return instance; + } + private DevStudioMIDLCompiler(boolean newEnvironment, Environment env) { + super("midl", null, new String[]{".idl", ".odl"}, new String[]{}, + ".tlb", false, null, newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + } + protected void addWarningSwitch(Vector args, int level) { + DevStudioProcessor.addWarningSwitch(args, level); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new DevStudioMIDLCompiler(newEnvironment, env); + } + return this; + } + /** + * The include parser for C will work just fine, but we didn't want to + * inherit from CommandLineCCompiler + */ + protected Parser createParser(File source) { + return new CParser(); + } + protected int getArgumentCountPerInputFile() { + return 3; + } + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + DevStudioProcessor.getDefineSwitch(buffer, define, value); + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ";"); + } + protected String getIncludeDirSwitch(String includeDir) { + return DevStudioProcessor.getIncludeDirSwitch(includeDir); + } + protected String getInputFileArgument(File outputDir, String filename, + int index) { + switch (index) { + case 0 : + return "/tlb"; + case 1 : + return new File(outputDir, getOutputFileNames(filename, null)[0]) + .getAbsolutePath(); + } + return filename; + } + public Linker getLinker(LinkType type) { + return DevStudioLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } + protected int getMaximumInputFilesPerCommand() { + return 1; + } + protected int getTotalArgumentLengthForInputFile(File outputDir, + String inputFile) { + String arg1 = getInputFileArgument(outputDir, inputFile, 0); + String arg2 = getInputFileArgument(outputDir, inputFile, 1); + String arg3 = getInputFileArgument(outputDir, inputFile, 2); + return arg1.length() + arg2.length() + arg3.length() + 3; + } + protected void getUndefineSwitch(StringBuffer buffer, String define) { + DevStudioProcessor.getUndefineSwitch(buffer, define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java new file mode 100644 index 0000000..8257c09 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java @@ -0,0 +1,90 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.util.Vector; +/** + * A add-in class for Microsoft Developer Studio processors + * + * + */ +public class DevStudioProcessor { + public static void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("/W0"); + break; + case 1 : + args.addElement("/W1"); + break; + case 2 : + break; + case 3 : + args.addElement("/W3"); + break; + case 4 : + args.addElement("/W4"); + break; + case 5 : + args.addElement("/WX"); + break; + } + } + public static String getCommandFileSwitch(String cmdFile) { + StringBuffer buf = new StringBuffer("@"); + if (cmdFile.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(cmdFile.replace('/', '\\')); + buf.append('\"'); + } else { + buf.append(cmdFile); + } + return buf.toString(); + } + public static void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("/D"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + public static String getIncludeDirSwitch(String includeDir) { + return "/I" + includeDir.replace('/', '\\'); + } + public static String[] getOutputFileSwitch(String outPath) { + StringBuffer buf = new StringBuffer("/Fo"); + if (outPath.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + String[] retval = new String[]{buf.toString()}; + return retval; + } + public static void getUndefineSwitch(StringBuffer buffer, String define) { + buffer.append("/U"); + buffer.append(define); + } + public static boolean isCaseSensitive() { + return false; + } + private DevStudioProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java new file mode 100644 index 0000000..51ab1dd --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioProjectWriter.java @@ -0,0 +1,710 @@ +/* + * + * Copyright 2004-2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.ide.DependencyDef; +import net.sf.antcontrib.cpptasks.ide.ProjectDef; +import net.sf.antcontrib.cpptasks.ide.ProjectWriter; +import net.sf.antcontrib.cpptasks.ide.CommentDef; +import org.apache.tools.ant.BuildException; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.*; +import java.text.MessageFormat; + +/** + * Writes a Microsoft Visual Studio 97 or Visual Studio 6 project file. + * + * Status: Collects file list but does not pick + * up libraries and settings from project. + * + * @author curta + */ +public final class DevStudioProjectWriter + implements ProjectWriter { + /** + * Visual Studio version. + */ + private String version; + + /** + * Constructor. + * @param versionArg String Visual Studio version. + */ + public DevStudioProjectWriter(final String versionArg) { + this.version = versionArg; + } + + private static String toProjectName(final String name) { + // + // some characters are apparently not allowed in VS project names + // but have not been able to find them documented + // limiting characters to alphas, numerics and hyphens + StringBuffer projectNameBuf = new StringBuffer(name); + for (int i = 0; i < projectNameBuf.length(); i++) { + final char ch = projectNameBuf.charAt(i); + if (!((ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') + || (ch >= '0' && ch <= '9'))) { + projectNameBuf.setCharAt(i, '_'); + } + } + return projectNameBuf.toString(); + + } + + /** + * Writes a project definition file. + * @param fileName File name base, writer may append appropriate extension + * @param task cc task for which to write project + * @param projectDef project element + * @param files source files + * @param targets compilation targets + * @param linkTarget link target + * @throws IOException if error writing project file + */ + public void writeProject(final File fileName, + final CCTask task, + final ProjectDef projectDef, + final List files, + final Hashtable targets, + final TargetInfo linkTarget) throws IOException { + + // + // some characters are apparently not allowed in VS project names + // but have not been able to find them documented + // limiting characters to alphas, numerics and hyphens + String projectName = projectDef.getName(); + if (projectName != null) { + projectName = toProjectName(projectName); + } else { + projectName = toProjectName(fileName.getName()); + } + + final String basePath = fileName.getAbsoluteFile().getParent(); + + File dspFile = new File(fileName + ".dsp"); + if (!projectDef.getOverwrite() && dspFile.exists()) { + throw new BuildException("Not allowed to overwrite project file " + + dspFile.toString()); + } + File dswFile = new File(fileName + ".dsw"); + if (!projectDef.getOverwrite() && dswFile.exists()) { + throw new BuildException("Not allowed to overwrite project file " + + dswFile.toString()); + } + + CommandLineCompilerConfiguration compilerConfig = + getBaseCompilerConfiguration(targets); + if (compilerConfig == null) { + throw new BuildException( + "Unable to generate Visual Studio project " + + "when Microsoft C++ is not used."); + } + + Writer writer = new BufferedWriter(new FileWriter(dspFile)); + writer.write("# Microsoft Developer Studio Project File - Name=\""); + writer.write(projectName); + writer.write("\" - Package Owner=<4>\r\n"); + writer.write( + "# Microsoft Developer Studio Generated Build File, Format Version "); + writer.write(this.version); + writer.write("\r\n"); + writer.write("# ** DO NOT EDIT **\r\n\r\n"); + + writeComments(writer, projectDef.getComments()); + + String outputType = task.getOuttype(); + String subsystem = task.getSubsystem(); + String targtype = "Win32 (x86) Dynamic-Link Library"; + String targid = "0x0102"; + if ("executable".equals(outputType)) { + if ("console".equals(subsystem)) { + targtype = "Win32 (x86) Console Application"; + targid = "0x0103"; + } else { + targtype = "Win32 (x86) Application"; + targid = "0x0101"; + } + } else if ("static".equals(outputType)) { + targtype = "Win32 (x86) Static Library"; + targid = "0x0104"; + } + writer.write("# TARGTYPE \""); + writer.write(targtype); + writer.write("\" "); + writer.write(targid); + writer.write("\r\n\r\nCFG="); + + writer.write(projectName + " - Win32 Debug"); + writer.write("\r\n"); + + writeMessage(writer, projectName, targtype); + + writer.write("# Begin Project\r\n"); + if (version.equals("6.00")) { + writer.write("# PROP AllowPerConfigDependencies 0\r\n"); + } + writer.write("# PROP Scc_ProjName \"\"\r\n"); + writer.write("# PROP Scc_LocalPath \"\"\r\n"); + writer.write("CPP=cl.exe\r\n"); + writer.write("MTL=midl.exe\r\n"); + writer.write("RSC=rc.exe\r\n"); + + writer.write("\r\n!IF \"$(CFG)\" == \"" + projectName + " - Win32 Release\"\r\n"); + + writeConfig(writer, false, projectDef.getDependencies(), basePath, compilerConfig, linkTarget, targets); + + writer.write("\r\n!ELSEIF \"$(CFG)\" == \"" + projectName + " - Win32 Debug\"\r\n"); + + writeConfig(writer, true, projectDef.getDependencies(), basePath, compilerConfig, linkTarget, targets); + + writer.write("\r\n!ENDIF\r\n"); + + writer.write("# Begin Target\r\n\r\n"); + writer.write("# Name \"" + projectName + " - Win32 Release\"\r\n"); + writer.write("# Name \"" + projectName + " - Win32 Debug\"\r\n"); + + + + File[] sortedSources = getSources(files); + + if (version.equals("6.00")) { + final String sourceFilter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"; + final String headerFilter = "h;hpp;hxx;hm;inl"; + final String resourceFilter = + "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"; + + writer.write("# Begin Group \"Source Files\"\r\n\r\n"); + writer.write("# PROP Default_Filter \"" + sourceFilter + "\"\r\n"); + + for (int i = 0; i < sortedSources.length; i++) { + if (!isGroupMember(headerFilter, sortedSources[i]) + && !isGroupMember(resourceFilter, sortedSources[i])) { + writeSource(writer, basePath, sortedSources[i]); + } + } + writer.write("# End Group\r\n"); + + writer.write("# Begin Group \"Header Files\"\r\n\r\n"); + writer.write("# PROP Default_Filter \"" + headerFilter + "\"\r\n"); + + for (int i = 0; i < sortedSources.length; i++) { + if (isGroupMember(headerFilter, sortedSources[i])) { + writeSource(writer, basePath, sortedSources[i]); + } + } + writer.write("# End Group\r\n"); + + writer.write("# Begin Group \"Resource Files\"\r\n\r\n"); + writer.write("# PROP Default_Filter \"" + resourceFilter + "\"\r\n"); + + for (int i = 0; i < sortedSources.length; i++) { + if (isGroupMember(resourceFilter, sortedSources[i])) { + writeSource(writer, basePath, sortedSources[i]); + } + } + writer.write("# End Group\r\n"); + + } else { + for (int i = 0; i < sortedSources.length; i++) { + writeSource(writer, basePath, sortedSources[i]); + } + } + + writer.write("# End Target\r\n"); + writer.write("# End Project\r\n"); + writer.close(); + + // + // write workspace file + // + writer = new BufferedWriter(new FileWriter(dswFile)); + writeWorkspace(writer, projectDef, projectName, dspFile); + writer.close(); + + } + + private void writeConfig(final Writer writer, + boolean isDebug, + final List dependencies, + final String basePath, + CommandLineCompilerConfiguration compilerConfig, + TargetInfo linkTarget, + Hashtable targets) throws IOException { + writer.write("# PROP BASE Use_MFC 0\r\n"); + + String configType = "Release"; + String configInt = "0"; + String configMacro = "NDEBUG"; + if (isDebug) { + configType = "Debug"; + configInt = "1"; + configMacro = "_DEBUG"; + } + + writer.write("# PROP BASE Use_Debug_Libraries "); + writer.write(configInt); + writer.write("\r\n# PROP BASE Output_Dir \""); + writer.write(configType); + writer.write("\"\r\n"); + writer.write("# PROP BASE Intermediate_Dir \""); + writer.write(configType); + writer.write("\"\r\n"); + writer.write("# PROP BASE Target_Dir \"\"\r\n"); + writer.write("# PROP Use_MFC 0\r\n"); + writer.write("# PROP Use_Debug_Libraries "); + writer.write(configInt); + writer.write("\r\n# PROP Output_Dir \""); + writer.write(configType); + writer.write("\"\r\n"); + writer.write("# PROP Intermediate_Dir \""); + writer.write(configType); + writer.write("\"\r\n"); + writer.write("# PROP Target_Dir \"\"\r\n"); + writeCompileOptions(writer, isDebug, basePath, compilerConfig); + writer.write( + "# ADD BASE MTL /nologo /D \"" + configMacro + "\" /mktyplib203 /o NUL /win32\r\n"); + writer.write( + "# ADD MTL /nologo /D \"" + configMacro + "\" /mktyplib203 /o NUL /win32\r\n"); + writer.write("# ADD BASE RSC /l 0x409 /d \"" + configMacro + "\"\r\n"); + writer.write("# ADD RSC /l 0x409 /d \"" + configMacro + "\"\r\n"); + writer.write("BSC32=bscmake.exe\r\n"); + writer.write("# ADD BASE BSC32 /nologo\r\n"); + writer.write("# ADD BSC32 /nologo\r\n"); + writer.write("LINK32=link.exe\r\n"); + writeLinkOptions(writer, isDebug, dependencies, basePath, linkTarget, targets); + } + private static void writeWorkspaceProject(final Writer writer, + final String projectName, + final String projectFile, + final List dependsOn) throws IOException { + writer.write("############################################"); + writer.write("###################################\r\n\r\n"); + String file = projectFile; + if(!file.startsWith(".") && !file.startsWith("\\") && !file.startsWith("/")) { + file = ".\\" + file; + } + writer.write("Project: \"" + projectName + "\"=\"" + + file + + "\" - Package Owner=<4>\r\n\r\n"); + + writer.write("Package=<5>\r\n{{{\r\n}}}\r\n\r\n"); + writer.write("Package=<4>\r\n{{{\r\n"); + if (dependsOn != null) { + for(Iterator iter = dependsOn.iterator(); iter.hasNext();) { + writer.write(" Begin Project Dependency\r\n"); + writer.write(" Project_Dep_Name " + toProjectName(String.valueOf(iter.next())) + "\r\n"); + writer.write(" End Project Dependency\r\n"); + } + } + writer.write("}}}\r\n\r\n"); + + } + + private void writeWorkspace(final Writer writer, + final ProjectDef project, + final String projectName, + final File dspFile) throws IOException { + + writer.write("Microsoft Developer Studio Workspace File, Format Version "); + writer.write(version); + writer.write("\r\n"); + writer.write("# WARNING: DO NOT EDIT OR DELETE"); + writer.write(" THIS WORKSPACE FILE!\r\n\r\n"); + + writeComments(writer, project.getComments()); + + + List dependencies = project.getDependencies(); + List projectDeps = new ArrayList(); + String basePath = dspFile.getParent(); + for(Iterator iter = dependencies.iterator(); iter.hasNext();) { + DependencyDef dep = (DependencyDef) iter.next(); + if (dep.getFile() != null) { + String projName = toProjectName(dep.getName()); + projectDeps.add(projName); + String depProject = CUtil.toWindowsPath( + CUtil.getRelativePath(basePath, + new File(dep.getFile() + ".dsp"))); + writeWorkspaceProject(writer, projName, depProject, dep.getDependsList()); + } + } + + writeWorkspaceProject(writer, projectName, dspFile.getName(), projectDeps); + + writer.write("############################################"); + writer.write("###################################\r\n\r\n"); + + + writer.write("Global:\r\n\r\nPackage=<5>\r\n{{{\r\n}}}"); + writer.write("\r\n\r\nPackage=<3>\r\n{{{\r\n}}}\r\n\r\n"); + + writer.write("########################################"); + writer.write("#######################################\r\n\r\n"); + + } + + /** + * Returns true if the file has an extension that appears in the group filter. + * @param filter String group filter + * @param candidate File file + * @return boolean true if member of group + */ + private boolean isGroupMember(final String filter, final File candidate) { + String fileName = candidate.getName(); + int lastDot = fileName.lastIndexOf('.'); + if (lastDot >= 0 && lastDot < fileName.length() - 1) { + String extension = + ";" + fileName.substring(lastDot + 1).toLowerCase() + ";"; + String semiFilter = ";" + filter + ";"; + return semiFilter.indexOf(extension) >= 0; + } + return false; + } + + /** + * Writes the entry for one source file in the project. + * @param writer Writer writer + * @param basePath String base path for project + * @param groupMember File project source file + * @throws IOException if error writing project file + */ + private void writeSource(final Writer writer, + final String basePath, + final File groupMember) + throws IOException { + writer.write("# Begin Source File\r\n\r\nSOURCE="); + String relativePath = CUtil.getRelativePath(basePath, + groupMember); + // + // if relative path is just a name (hello.c) then + // make it .\hello.c + if (!relativePath.startsWith(".") + && relativePath.indexOf(":") < 0 + && !relativePath.startsWith("\\")) { + relativePath = ".\\" + relativePath; + } + writer.write(CUtil.toWindowsPath(relativePath)); + writer.write("\r\n# End Source File\r\n"); + } + + /** + * Get alphabetized array of source files. + * @param sourceList list of source files + * @return File[] source files + */ + private File[] getSources(final List sourceList) { + File[] sortedSources = new File[sourceList.size()]; + sourceList.toArray(sortedSources); + Arrays.sort(sortedSources, new Comparator() { + public int compare(final Object o1, final Object o2) { + return ((File) o1).getName().compareTo(((File) o2).getName()); + } + }); + return sortedSources; + } + + /** + * Writes "This is not a makefile" warning. + * @param writer Writer writer + * @param projectName String project name + * @param targtype String target type + * @throws IOException if error writing project + */ + + private void writeMessage(final Writer writer, + final String projectName, + final String targtype) throws IOException { + writer.write( + "!MESSAGE This is not a valid makefile. "); + writer.write("To build this project using NMAKE,\r\n"); + writer.write("!MESSAGE use the Export Makefile command and run\r\n"); + writer.write("!MESSAGE \r\n"); + writer.write("!MESSAGE NMAKE /f \""); + writer.write(projectName); + writer.write(".mak\".\r\n"); + writer.write("!MESSAGE \r\n"); + writer.write( + "!MESSAGE You can specify a configuration when running NMAKE\r\n"); + writer.write( + "!MESSAGE by defining the macro CFG on the command line. "); + writer.write("For example:\r\n"); + writer.write("!MESSAGE \r\n"); + writer.write("!MESSAGE NMAKE /f \""); + writer.write(projectName); + writer.write(".mak\" CFG=\""); + writer.write(projectName); + writer.write(" - Win32 Debug\"\r\n"); + writer.write("!MESSAGE \r\n"); + writer.write("!MESSAGE Possible choices for configuration are:\r\n"); + writer.write("!MESSAGE \r\n"); + String pattern = "!MESSAGE \"{0} - Win32 {1}\" (based on \"{2}\")\r\n"; + writer.write(MessageFormat.format(pattern, new Object[] { projectName, "Release", targtype })); + writer.write(MessageFormat.format(pattern, new Object[] { projectName, "Debug", targtype })); + writer.write("!MESSAGE \r\n"); + writer.write("\r\n"); + + } + + /** + * Gets the first recognized compiler from the + * compilation targets. + * @param targets compilation targets + * @return representative (hopefully) compiler configuration + */ + private CommandLineCompilerConfiguration + getBaseCompilerConfiguration(final Hashtable targets) { + // + // find first target with an DevStudio C compilation + // + CommandLineCompilerConfiguration compilerConfig; + // + // get the first target and assume that it is representative + // + Iterator targetIter = targets.values().iterator(); + while (targetIter.hasNext()) { + TargetInfo targetInfo = (TargetInfo) targetIter.next(); + ProcessorConfiguration config = targetInfo.getConfiguration(); + // + // for the first cl compiler + // + if (config instanceof CommandLineCompilerConfiguration) { + compilerConfig = (CommandLineCompilerConfiguration) config; + if (compilerConfig.getCompiler() instanceof DevStudioCCompiler) { + return compilerConfig; + } + } + } + return null; + } + + /** + * Writes compiler options. + * @param writer Writer writer + * @param isDebug true if debug. + * @param baseDir String base directory + * @param compilerConfig compiler configuration + * @throws IOException if error on writing project + */ + private void writeCompileOptions(final Writer writer, + final boolean isDebug, + final String baseDir, + final CommandLineCompilerConfiguration + compilerConfig) throws IOException { + StringBuffer baseOptions = new StringBuffer(50); + baseOptions.append("# ADD BASE CPP"); + StringBuffer options = new StringBuffer(50); + options.append("# ADD CPP"); + File[] includePath = compilerConfig.getIncludePath(); + for (int i = 0; i < includePath.length; i++) { + options.append(" /I \""); + String relPath = CUtil.getRelativePath(baseDir, includePath[i]); + options.append(CUtil.toWindowsPath(relPath)); + options.append('"'); + } + Hashtable optionMap = new Hashtable(); + + if (isDebug) { + // + // release options that should be mapped to debug counterparts + // + optionMap.put("/MT", "/MTd"); + optionMap.put("/ML", "/MLd"); + optionMap.put("/MD", "/MDd"); + optionMap.put("/O2", "/Od"); + optionMap.put("/O3", "/Od"); + } else { + // + // debug options that should be mapped to release counterparts + // + optionMap.put("/MTD", "/MT"); + optionMap.put("/MLD", "/ML"); + optionMap.put("/MDD", "/MD"); + optionMap.put("/GM", ""); + optionMap.put("/ZI", ""); + optionMap.put("/OD", "/O2"); + optionMap.put("/GZ", ""); + } + + + + String[] preArgs = compilerConfig.getPreArguments(); + for (int i = 0; i < preArgs.length; i++) { + if (preArgs[i].startsWith("/D")) { + options.append(" /D "); + baseOptions.append(" /D "); + String body = preArgs[i].substring(2); + if (preArgs[i].indexOf('=') >= 0) { + options.append(body); + baseOptions.append(body); + } else { + StringBuffer buf = new StringBuffer("\""); + if ("NDEBUG".equals(body) || "_DEBUG".equals(body)) { + if (isDebug) { + buf.append("_DEBUG"); + } else { + buf.append("NDEBUG"); + } + } else { + buf.append(body); + } + buf.append("\""); + options.append(buf); + baseOptions.append(buf); + } + } else if (!preArgs[i].startsWith("/I")) { + String option = preArgs[i]; + String key = option.toUpperCase(Locale.US); + if (optionMap.containsKey(key)) { + option = optionMap.get(key).toString(); + } + options.append(" "); + options.append(option); + baseOptions.append(" "); + baseOptions.append(option); + } + } + baseOptions.append("\r\n"); + options.append("\r\n"); + writer.write(baseOptions.toString()); + writer.write(options.toString()); + + } + + + + + + /** + * Writes link options. + * @param writer Writer writer + * @param basePath String base path + * @param dependencies project dependencies, used to suppress explicit linking. + * @param linkTarget TargetInfo link target + * @param targets Hashtable all targets + * @throws IOException if unable to write to project file + */ + private void writeLinkOptions(final Writer writer, + final boolean isDebug, + final List dependencies, + final String basePath, + final TargetInfo linkTarget, + final Hashtable targets) throws IOException { + + StringBuffer baseOptions = new StringBuffer(100); + StringBuffer options = new StringBuffer(100); + baseOptions.append("# ADD BASE LINK32"); + options.append("# ADD LINK32"); + + ProcessorConfiguration config = linkTarget.getConfiguration(); + if (config instanceof CommandLineLinkerConfiguration) { + CommandLineLinkerConfiguration linkConfig = + (CommandLineLinkerConfiguration) config; + + File[] linkSources = linkTarget.getAllSources(); + for (int i = 0; i < linkSources.length; i++) { + // + // if file was not compiled or otherwise generated + // + if (targets.get(linkSources[i].getName()) == null) { + // + // if source appears to be a system library or object file + // just output the name of the file (advapi.lib for example) + // otherwise construct a relative path. + // + String relPath = linkSources[i].getName(); + // + // check if file comes from a project dependency + // if it does it should not be explicitly linked + boolean fromDependency = false; + if (relPath.indexOf(".") > 0) { + String baseName = relPath.substring(0, relPath.indexOf(".")); + for(Iterator iter = dependencies.iterator(); iter.hasNext(); ) { + DependencyDef depend = (DependencyDef) iter.next(); + if (baseName.compareToIgnoreCase(depend.getName()) == 0) { + fromDependency = true; + } + } + } + if (!fromDependency) { + if (!CUtil.isSystemPath(linkSources[i])) { + relPath = CUtil.getRelativePath(basePath, linkSources[i]); + } + // + // if path has an embedded space then + // must quote + if (relPath.indexOf(' ') > 0) { + options.append(" \""); + options.append(CUtil.toWindowsPath(relPath)); + options.append("\""); + } else { + options.append(' '); + options.append(CUtil.toWindowsPath(relPath)); + } + } + } + } + String[] preArgs = linkConfig.getPreArguments(); + for (int i = 0; i < preArgs.length; i++) { + if (isDebug || !preArgs[i].equals("/DEBUG")) { + options.append(' '); + options.append(preArgs[i]); + baseOptions.append(' '); + baseOptions.append(preArgs[i]); + } + } + String[] endArgs = linkConfig.getEndArguments(); + for (int i = 0; i < endArgs.length; i++) { + options.append(' '); + options.append(endArgs[i]); + baseOptions.append(' '); + baseOptions.append(endArgs[i]); + } + } + baseOptions.append("\r\n"); + options.append("\r\n"); + writer.write(baseOptions.toString()); + writer.write(options.toString()); + } + + private static void writeComments(final Writer writer, + final List comments) throws IOException { + for(Iterator iter = comments.iterator();iter.hasNext();) { + String comment = ((CommentDef) iter.next()).getText(); + if (comment != null) { + int start = 0; + for(int end = comment.indexOf('\n'); + end != -1; + end = comment.indexOf('\n', start)) { + writer.write("#" + comment.substring(start, end) + "\r\n"); + start = end + 1; + } + } + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java new file mode 100644 index 0000000..6f8360b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java @@ -0,0 +1,119 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Microsoft (r) Windows 32 Resource Compiler + * + * @author Curt Arnold + */ +public final class DevStudioResourceCompiler extends CommandLineCompiler { + private static final DevStudioResourceCompiler instance = new DevStudioResourceCompiler( + false, null); + public static DevStudioResourceCompiler getInstance() { + return instance; + } + private String identifier; + private DevStudioResourceCompiler(boolean newEnvironment, Environment env) { + super("rc", null, new String[]{".rc"}, new String[]{".h", ".hpp", + ".inl"}, ".res", false, null, newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + if (debug) { + args.addElement("/D_DEBUG"); + } else { + args.addElement("/DNDEBUG"); + } + } + protected void addWarningSwitch(Vector args, int level) { + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new DevStudioResourceCompiler(newEnvironment, env); + } + return this; + } + /** + * The include parser for C will work just fine, but we didn't want to + * inherit from CommandLineCCompiler + */ + protected Parser createParser(File source) { + return new CParser(); + } + protected int getArgumentCountPerInputFile() { + return 2; + } + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + DevStudioProcessor.getDefineSwitch(buffer, define, value); + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ";"); + } + protected String getIncludeDirSwitch(String includeDir) { + return DevStudioProcessor.getIncludeDirSwitch(includeDir); + } + protected String getInputFileArgument(File outputDir, String filename, + int index) { + if (index == 0) { + String outputFileName = getOutputFileNames(filename, null)[0]; + String fullOutputName = new File(outputDir, outputFileName) + .toString(); + return "/fo" + fullOutputName; + } + return filename; + } + public Linker getLinker(LinkType type) { + return DevStudioLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } + protected int getMaximumInputFilesPerCommand() { + return 1; + } + protected int getTotalArgumentLengthForInputFile(File outputDir, + String inputFile) { + String arg1 = getInputFileArgument(outputDir, inputFile, 0); + String arg2 = getInputFileArgument(outputDir, inputFile, 1); + return arg1.length() + arg2.length() + 2; + } + protected void getUndefineSwitch(StringBuffer buffer, String define) { + DevStudioProcessor.getUndefineSwitch(buffer, define); + } + public String getIdentifier() { + return "Microsoft (R) Windows (R) Resource Compiler"; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java new file mode 100644 index 0000000..f554e09 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/VisualStudioNETProjectWriter.java @@ -0,0 +1,866 @@ +/* + * + * Copyright 2004-2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.ide.ProjectDef; +import net.sf.antcontrib.cpptasks.ide.CommentDef; +import net.sf.antcontrib.cpptasks.ide.ProjectWriter; +import net.sf.antcontrib.cpptasks.ide.DependencyDef; +import org.apache.tools.ant.BuildException; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Writes a Visual Studio.NET project file. + * + * @author curta + */ +public final class VisualStudioNETProjectWriter + implements ProjectWriter { + /** + * Version of VisualStudio.NET. + */ + private final String version; + + /** + * Literal to represent a true value. + */ + private final String trueLiteral; + + /** + * Literal to represent a false value. + */ + private final String falseLiteral; + + /** + * Constructor. + * + * @param versionArg String VisualStudio.NET version + * @param trueArg literal to represent true, "true" in VC 2005. + * @param falseArg literal to represent false, "false" in VC 2005. + */ + public VisualStudioNETProjectWriter(final String versionArg, + final String trueArg, + final String falseArg) { + if (versionArg == null) { + throw new IllegalArgumentException("versionArg"); + } + if (trueArg == null) { + throw new IllegalArgumentException("trueArg"); + } + if (falseArg == null) { + throw new IllegalArgumentException("falseArg"); + } + this.version = versionArg; + this.trueLiteral = trueArg; + this.falseLiteral = falseArg; + } + + + + /** + * Gets the configuration type. + * + * @param task cc task, may not be null. + * @return configuration type + */ + private String getConfigurationType(final CCTask task) { + String outputType = task.getOuttype(); + String targtype = "2"; // Win32 (x86) Dynamic-Link Library"; + if ("executable".equals(outputType)) { + targtype = "1"; // "Win32 (x86) Console Application"; + } else if ("static".equals(outputType)) { + targtype = "4"; //"Win32 (x86) Static Library"; + } + return targtype; + } + + + + /** + * Get character set for Windows API. + * @param compilerConfig compiler configuration, may not be null. + * @return "1" is TCHAR is unicode, "0" if TCHAR is multi-byte. + */ + private String getCharacterSet( + final CommandLineCompilerConfiguration compilerConfig) { + String[] args = compilerConfig.getPreArguments(); + String charset = "0"; + for (int i = 0; i < args.length; i++) { + if ("/D_UNICODE".equals(args[i]) || "/DUNICODE".equals(args[i])) { + charset = "1"; + } + if ("/D_MBCS".equals(args[i])) { + charset = "2"; + } + } + return charset; + } + + /** + * Write the start tag of the Configuration element. + * @param content serialization content handler. + * @param isDebug if true, write a debug configuration. + * @param task cc task. + * @param compilerConfig compiler configuration. + * @throws SAXException thrown if serialization error. + */ + private void writeConfigurationStartTag(final ContentHandler content, + final boolean isDebug, + final CCTask task, + final CommandLineCompilerConfiguration compilerConfig) + throws SAXException { + AttributesImpl attributes = new AttributesImpl(); + if (isDebug) { + addAttribute(attributes, "Name", "Debug|Win32"); + addAttribute(attributes, "OutputDirectory", "Debug"); + addAttribute(attributes, "IntermediateDirectory", "Debug"); + } else { + addAttribute(attributes, "Name", "Release|Win32"); + addAttribute(attributes, "OutputDirectory", "Release"); + addAttribute(attributes, "IntermediateDirectory", "Release"); + + } + addAttribute(attributes, "ConfigurationType", + getConfigurationType(task)); + addAttribute(attributes, "CharacterSet", + getCharacterSet(compilerConfig)); + content.startElement(null, + "Configuration", "Configuration", attributes); + } + + /** + * Get value of Optimization property. + * @param compilerConfig compiler configuration, may not be null. + * @return value of Optimization property. + */ + private String getOptimization( + final CommandLineCompilerConfiguration compilerConfig) { + String[] args = compilerConfig.getPreArguments(); + String opt = "0"; + for (int i = 0; i < args.length; i++) { + if ("/Od".equals(args[i])) { + opt = "0"; + } + if ("/O1".equals(args[i])) { + opt = "1"; + } + if ("/O2".equals(args[i])) { + opt = "2"; + } + if ("/Ox".equals(args[i])) { + opt = "3"; + } + } + return opt; + } + + /** + * Get value of AdditionalIncludeDirectories property. + * @param compilerConfig compiler configuration. + * @param baseDir base for relative paths. + * @return value of AdditionalIncludeDirectories property. + */ + private String getAdditionalIncludeDirectories( + final String baseDir, + final CommandLineCompilerConfiguration compilerConfig) { + File[] includePath = compilerConfig.getIncludePath(); + StringBuffer includeDirs = new StringBuffer(); + for (int i = 0; i < includePath.length; i++) { + String relPath = CUtil.getRelativePath(baseDir, includePath[i]); + includeDirs.append(CUtil.toWindowsPath(relPath)); + includeDirs.append(';'); + } + + + if (includeDirs.length() > 0) { + includeDirs.setLength(includeDirs.length() - 1); + } + return includeDirs.toString(); + } + + /** + * Get value of PreprocessorDefinitions property. + * @param compilerConfig compiler configuration. + * @param isDebug true if generating debug configuration. + * @return value of PreprocessorDefinitions property. + */ + private String getPreprocessorDefinitions( + final CommandLineCompilerConfiguration compilerConfig, + final boolean isDebug) { + StringBuffer defines = new StringBuffer(); + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("/D")) { + String macro = args[i].substring(2); + if (isDebug) { + if (macro.equals("NDEBUG")) { + macro = "_DEBUG"; + } + } else { + if (macro.equals("_DEBUG")) { + macro = "NDEBUG"; + } + } + defines.append(macro); + defines.append(";"); + } + } + + if (defines.length() > 0) { + defines.setLength(defines.length() - 1); + } + return defines.toString(); + } + + /** + * Get value of RuntimeLibrary property. + * @param compilerConfig compiler configuration. + * @param isDebug true if generating debug configuration. + * @return value of RuntimeLibrary property. + */ + private String getRuntimeLibrary( + final CommandLineCompilerConfiguration compilerConfig, + final boolean isDebug) { + String rtl = null; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("/MT")) { + if (isDebug) { + rtl = "1"; + } else { + rtl = "0"; + } + } else if (args[i].startsWith("/MD")) { + if (isDebug) { + rtl = "3"; + } else { + rtl = "2"; + } + } + } + return rtl; + } + + /** + * Get value of UsePrecompiledHeader property. + * @param compilerConfig compiler configuration. + * @return value of UsePrecompiledHeader property. + */ + private String getUsePrecompiledHeader( + final CommandLineCompilerConfiguration compilerConfig) { + String usePCH = "0"; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/Yc".equals(args[i])) { + usePCH = "1"; + } + if ("/Yu".equals(args[i])) { + usePCH = "2"; + } + } + return usePCH; + } + + /** + * Get value of PrecompiledHeaderFile property. + * @param compilerConfig compiler configuration. + * @return value of PrecompiledHeaderFile property. + */ + private String getPrecompiledHeaderFile( + final CommandLineCompilerConfiguration compilerConfig) { + String pch = null; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("/Fp")) { + pch = args[i].substring(3); + } + } + return pch; + } + + + + /** + * Get value of BasicRuntimeChecks property. + * @param compilerConfig compiler configuration. + * @return value of BasicRuntimeChecks property. + */ + private String getBasicRuntimeChecks( + final CommandLineCompilerConfiguration compilerConfig) { + String checks = "0"; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/RTCs".equals(args[i])) { + checks = "1"; + } + if ("/RTCu".equals(args[i])) { + checks = "2"; + } + if ("/RTC1".equals(args[i]) || "/GZ".equals(args[i])) { + checks = "3"; + } + } + return checks; + } + + /** + * Get value of WarningLevel property. + * @param compilerConfig compiler configuration. + * @return value of WarningLevel property. + */ + private String getWarningLevel( + final CommandLineCompilerConfiguration compilerConfig) { + String warn = null; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/W0".equals(args[i])) { + warn = "0"; + } + if ("/W1".equals(args[i])) { + warn = "1"; + } + if ("/W2".equals(args[i])) { + warn = "2"; + } + if ("/W3".equals(args[i])) { + warn = "3"; + } + } + return warn; + } + + /** + * Get value of Detect64BitPortabilityProblems property. + * @param compilerConfig compiler configuration. + * @return value of Detect64BitPortabilityProblems property. + */ + private String getDetect64BitPortabilityProblems( + final CommandLineCompilerConfiguration compilerConfig) { + String warn64 = null; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/Wp64".equals(args[i])) { + warn64 = trueLiteral; + } + } + return warn64; + } + + /** + * Get value of DebugInformationFormat property. + * @param compilerConfig compiler configuration. + * @return value of DebugInformationFormat property. + */ + private String getDebugInformationFormat( + final CommandLineCompilerConfiguration compilerConfig) { + String format = "0"; + String[] args = compilerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/Z7".equals(args[i])) { + format = "1"; + } + if ("/Zd".equals(args[i])) { + format = "2"; + } + if ("/Zi".equals(args[i])) { + format = "3"; + } + if ("/ZI".equals(args[i])) { + format = "4"; + } + } + return format; + } + + /** + * write the Compiler element. + * @param content serialization content handler. + * @param isDebug true if generating debug configuration. + * @param basePath base for relative file paths. + * @param compilerConfig compiler configuration. + * @throws SAXException thrown if error during serialization. + */ + private void writeCompilerElement(final ContentHandler content, + final boolean isDebug, + final String basePath, + final CommandLineCompilerConfiguration compilerConfig) + throws SAXException { + AttributesImpl attributes = new AttributesImpl(); + addAttribute(attributes, "Name", "VCCLCompilerTool"); + String optimization = getOptimization(compilerConfig); + String debugFormat = getDebugInformationFormat(compilerConfig); + if(isDebug) { + optimization = "0"; + if ("0".equals(debugFormat)) { + debugFormat = "4"; + } + } else { + if ("0".equals(optimization)) { + optimization = "2"; + } + debugFormat = "0"; + } + addAttribute(attributes, "Optimization", optimization); + addAttribute(attributes, "AdditionalIncludeDirectories", + getAdditionalIncludeDirectories(basePath, compilerConfig)); + addAttribute(attributes, "PreprocessorDefinitions", + getPreprocessorDefinitions(compilerConfig, isDebug)); + addAttribute(attributes, "MinimalRebuild", trueLiteral); + addAttribute(attributes, "BasicRuntimeChecks", + getBasicRuntimeChecks(compilerConfig)); + addAttribute(attributes, "RuntimeLibrary", + getRuntimeLibrary(compilerConfig, isDebug)); + addAttribute(attributes, "UsePrecompiledHeader", + getUsePrecompiledHeader(compilerConfig)); + addAttribute(attributes, "PrecompiledHeaderFile", + getPrecompiledHeaderFile(compilerConfig)); + addAttribute(attributes, "WarningLevel", + getWarningLevel(compilerConfig)); + addAttribute(attributes, "Detect64BitPortabilityProblems", + getDetect64BitPortabilityProblems(compilerConfig)); + addAttribute(attributes, "DebugInformationFormat", + debugFormat); + content.startElement(null, "Tool", "Tool", attributes); + content.endElement(null, "Tool", "Tool"); + + } + + + /** + * Get value of LinkIncremental property. + * @param linkerConfig linker configuration. + * @return value of LinkIncremental property + */ + private String getLinkIncremental( + final CommandLineLinkerConfiguration linkerConfig) { + String incremental = "0"; + String[] args = linkerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/INCREMENTAL:NO".equals(args[i])) { + incremental = "1"; + } + if ("/INCREMENTAL:YES".equals(args[i])) { + incremental = "2"; + } + } + return incremental; + } + + + /** + * Get value of Subsystem property. + * @param linkerConfig linker configuration. + * @return value of Subsystem property + */ + private String getSubsystem( + final CommandLineLinkerConfiguration linkerConfig) { + String subsystem = "0"; + String[] args = linkerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/SUBSYSTEM:CONSOLE".equals(args[i])) { + subsystem = "1"; + } + if ("/SUBSYSTEM:WINDOWS".equals(args[i])) { + subsystem = "2"; + } + if ("/SUBSYSTEM:WINDOWSCE".equals(args[i])) { + subsystem = "9"; + } + } + return subsystem; + } + + /** + * Get value of TargetMachine property. + * @param linkerConfig linker configuration. + * @return value of TargetMachine property + */ + private String getTargetMachine( + final CommandLineLinkerConfiguration linkerConfig) { + String subsystem = "0"; + String[] args = linkerConfig.getPreArguments(); + for (int i = 0; i < args.length; i++) { + if ("/MACHINE:X86".equals(args[i])) { + subsystem = "1"; + } + } + return subsystem; + } + + /** + * Get value of AdditionalDependencies property. + * @param linkTarget link target. + * @param projectDependencies dependencies declared in project. + * @param targets all targets. + * @param basePath path to directory containing project file. + * @return value of AdditionalDependencies property. + */ + private String getAdditionalDependencies(final TargetInfo linkTarget, + final List projectDependencies, + final Map targets, + final String basePath) { + String dependencies = null; + File[] linkSources = linkTarget.getAllSources(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < linkSources.length; i++) { + // + // if file was not compiled or otherwise generated + // + if (targets.get(linkSources[i].getName()) == null) { + // + // if source appears to be a system library or object file + // just output the name of the file (advapi.lib for example) + // otherwise construct a relative path. + // + String relPath = linkSources[i].getName(); + // + // check if file comes from a project dependency + // if it does it should not be explicitly linked + boolean fromDependency = false; + if (relPath.indexOf(".") > 0) { + String baseName = relPath.substring(0, relPath.indexOf(".")); + for(Iterator iter = projectDependencies.iterator(); iter.hasNext(); ) { + DependencyDef depend = (DependencyDef) iter.next(); + if (baseName.compareToIgnoreCase(depend.getName()) == 0) { + fromDependency = true; + } + } + } + + if (!fromDependency) { + if (!CUtil.isSystemPath(linkSources[i])) { + relPath = CUtil.getRelativePath(basePath, linkSources[i]); + } + // + // if path has an embedded space then + // must quote + if (relPath.indexOf(' ') > 0) { + buf.append('\"'); + buf.append(CUtil.toWindowsPath(relPath)); + buf.append('\"'); + } else { + buf.append(relPath); + } + buf.append(' '); + } + } + } + if (buf.length() > 0) { + buf.setLength(buf.length() - 1); + dependencies = buf.toString(); + } + return dependencies; + + } + + /** + * Write Tool element for linker. + * @param content serialization content handler. + * @param isDebug true if generating debug configuration. + * @param dependencies project dependencies. + * @param basePath path to directory containing project file. + * @param linkTarget link target. + * @param targets all targets. + * @throws SAXException thrown if error during serialization. + */ + private void writeLinkerElement(final ContentHandler content, + final boolean isDebug, + final List dependencies, + final String basePath, + final TargetInfo linkTarget, + final Map targets) throws SAXException { + AttributesImpl attributes = new AttributesImpl(); + addAttribute(attributes, "Name", "VCLinkerTool"); + + ProcessorConfiguration config = linkTarget.getConfiguration(); + if (config instanceof CommandLineLinkerConfiguration) { + CommandLineLinkerConfiguration linkerConfig = + (CommandLineLinkerConfiguration) config; + if (linkerConfig.getLinker() instanceof DevStudioCompatibleLinker) { + addAttribute(attributes, "LinkIncremental", + getLinkIncremental(linkerConfig)); + if (isDebug) { + addAttribute(attributes, "GenerateDebugInformation", trueLiteral); + } else { + addAttribute(attributes, "GenerateDebugInformation", falseLiteral); + } + addAttribute(attributes, "SubSystem", + getSubsystem(linkerConfig)); + addAttribute(attributes, "TargetMachine", + getTargetMachine(linkerConfig)); + } + } + addAttribute(attributes, "AdditionalDependencies", + getAdditionalDependencies(linkTarget, dependencies, targets, basePath)); + content.startElement(null, "Tool", "Tool", attributes); + content.endElement(null, "Tool", "Tool"); + } + + /** + * Writes a project definition file. + * + * @param fileName project name for file, should has .cbx extension + * @param task cc task for which to write project + * @param projectDef project element + * @param sources source files + * @param targets compilation targets + * @param linkTarget link target + * @throws IOException if I/O error + * @throws SAXException if XML serialization error + */ + public void writeProject(final File fileName, + final CCTask task, + final ProjectDef projectDef, + final List sources, + final Hashtable targets, + final TargetInfo linkTarget) throws + IOException, + SAXException { + + String projectName = projectDef.getName(); + if (projectName == null) { + projectName = fileName.getName(); + } + + + File vcprojFile = new File(fileName + ".vcproj"); + if (!projectDef.getOverwrite() && vcprojFile.exists()) { + throw new BuildException("Not allowed to overwrite project file " + + vcprojFile.toString()); + } + File slnFile = new File(fileName + ".sln"); + if (!projectDef.getOverwrite() && slnFile.exists()) { + throw new BuildException("Not allowed to overwrite project file " + + slnFile.toString()); + } + + CommandLineCompilerConfiguration compilerConfig = + getBaseCompilerConfiguration(targets); + if (compilerConfig == null) { + throw new BuildException( + "Unable to generate Visual Studio.NET project " + + "when Microsoft C++ is not used."); + } + + OutputStream outStream = new FileOutputStream(fileName + ".vcproj"); + OutputFormat format = new OutputFormat("xml", "UTF-8", true); + XMLSerializer serializer = new XMLSerializer(outStream, format); + ContentHandler content = serializer.asContentHandler(); + String basePath = fileName.getParentFile().getAbsolutePath(); + content.startDocument(); + + for(Iterator iter = projectDef.getComments().iterator(); iter.hasNext(); ) { + String comment = ((CommentDef) iter.next()).getText(); + serializer.comment(comment); + } + + AttributesImpl emptyAttrs = new AttributesImpl(); + + AttributesImpl attributes = new AttributesImpl(); + addAttribute(attributes, "ProjectType", "Visual C++"); + addAttribute(attributes, "Version", version); + addAttribute(attributes, "Name", projectName); + content.startElement(null, "VisualStudioProject", + "VisualStudioProject", attributes); + + content.startElement(null, "Platforms", "Platforms", emptyAttrs); + attributes.clear(); + addAttribute(attributes, "Name", "Win32"); + content.startElement(null, "Platform", "Platform", attributes); + content.endElement(null, "Platform", "Platform"); + content.endElement(null, "Platforms", "Platforms"); + content.startElement(null, "Configurations", + "Configurations", emptyAttrs); + + // + // write debug configuration + // + writeConfigurationStartTag(content, true, task, compilerConfig); + writeCompilerElement(content, true, basePath, compilerConfig); + writeLinkerElement(content, true, projectDef.getDependencies(), basePath, linkTarget, targets); + content.endElement(null, "Configuration", "Configuration"); + + // + // write release configuration + // + writeConfigurationStartTag(content, false, task, compilerConfig); + writeCompilerElement(content, false, basePath, compilerConfig); + writeLinkerElement(content, false, projectDef.getDependencies(), basePath, linkTarget, targets); + content.endElement(null, "Configuration", "Configuration"); + + content.endElement(null, "Configurations", "Configurations"); + content.startElement(null, "References", "References", emptyAttrs); + content.endElement(null, "References", "References"); + content.startElement(null, "Files", "Files", emptyAttrs); + + + File[] sortedSources = new File[sources.size()]; + sources.toArray(sortedSources); + Arrays.sort(sortedSources, new Comparator() { + public int compare(final Object o1, final Object o2) { + return ((File) o1).getName().compareTo(((File) o2).getName()); + } + }); + + writeFilteredSources("Source Files", + "cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx", + basePath, sortedSources, content); + + writeFilteredSources("Header Files", "h;hpp;hxx;hm;inl;inc;xsd", + basePath, sortedSources, content); + + writeFilteredSources("Resource Files", + "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx", + basePath, sortedSources, content); + + content.endElement(null, "Files", "Files"); + content.startElement(null, "Globals", "Globals", emptyAttrs); + content.endElement(null, "Globals", "Globals"); + content.endElement(null, "VisualStudioProject", "VisualStudioProject"); + content.endDocument(); + } + + /** + * Writes a cluster of source files to the project. + * + * @param name name of filter + * @param filter file extensions + * @param basePath base path for files + * @param sortedSources array of source files + * @param content generated project + * @throws SAXException if invalid content + */ + private void writeFilteredSources(final String name, final String filter, + final String basePath, + final File[] sortedSources, + final ContentHandler content) + throws SAXException { + AttributesImpl filterAttrs = new AttributesImpl(); + filterAttrs.addAttribute(null, "Name", "Name", "#PCDATA", name); + filterAttrs.addAttribute(null, "Filter", "Filter", "#PCDATA", filter); + content.startElement(null, "Filter", "Filter", filterAttrs); + + + AttributesImpl fileAttrs = new AttributesImpl(); + fileAttrs.addAttribute(null, "RelativePath", "RelativePath", + "#PCDATA", ""); + + + for (int i = 0; i < sortedSources.length; i++) { + if (isGroupMember(filter, sortedSources[i])) { + String relativePath = CUtil.getRelativePath(basePath, + sortedSources[i]); + fileAttrs.setValue(0, relativePath); + content.startElement(null, "File", "File", fileAttrs); + content.endElement(null, "File", "File"); + } + } + content.endElement(null, "Filter", "Filter"); + + } + + /** + * Returns true if the file has an extension that + * appears in the group filter. + * + * @param filter String group filter + * @param candidate File file + * @return boolean true if member of group + */ + private boolean isGroupMember(final String filter, final File candidate) { + String fileName = candidate.getName(); + int lastDot = fileName.lastIndexOf('.'); + if (lastDot >= 0 && lastDot < fileName.length() - 1) { + String extension = + ";" + fileName.substring(lastDot + 1).toLowerCase() + ";"; + String semiFilter = ";" + filter + ";"; + return semiFilter.indexOf(extension) >= 0; + } + return false; + } + + + /** + * Adds an non-namespace-qualified attribute to attribute list. + * @param attributes list of attributes. + * @param attrName attribute name, may not be null. + * @param attrValue attribute value, if null attribute is not added. + */ + private static void addAttribute(final AttributesImpl attributes, + final String attrName, + final String attrValue) { + if (attrName == null) { + throw new IllegalArgumentException("attrName"); + } + if (attrValue != null) { + attributes.addAttribute(null, attrName, attrName, + "#PCDATA", attrValue); + } + } + + /** + * Gets the first recognized compiler from the + * compilation targets. + * @param targets compilation targets + * @return representative (hopefully) compiler configuration + */ + private CommandLineCompilerConfiguration + getBaseCompilerConfiguration(final Hashtable targets) { + // + // get the first target and assume that it is representative + // + Iterator targetIter = targets.values().iterator(); + while (targetIter.hasNext()) { + TargetInfo targetInfo = (TargetInfo) targetIter.next(); + ProcessorConfiguration config = targetInfo.getConfiguration(); + // + // for the first cl compiler + // + if (config instanceof CommandLineCompilerConfiguration) { + CommandLineCompilerConfiguration compilerConfig = + (CommandLineCompilerConfiguration) config; + if (compilerConfig.getCompiler() + instanceof DevStudioCCompiler) { + return compilerConfig; + } + } + } + return null; + } +} + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html new file mode 100644 index 0000000..46a31b4 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/devstudio/package.html @@ -0,0 +1,27 @@ + + + + + + + +Adapters for Microsoft tools. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java new file mode 100644 index 0000000..2e8d4af --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java @@ -0,0 +1,107 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +import org.apache.tools.ant.BuildException; +/** + * Adapter for the "ar" tool + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public abstract class AbstractArLibrarian extends CommandLineLinker { + private/* final */ + String outputPrefix; + protected AbstractArLibrarian(String command, String identificationArg, + String[] inputExtensions, String[] ignoredExtensions, + String outputPrefix, String outputExtension, boolean isLibtool, + AbstractArLibrarian libtoolLibrarian) { + super(command, identificationArg, inputExtensions, ignoredExtensions, + outputExtension, isLibtool, libtoolLibrarian); + this.outputPrefix = outputPrefix; + } + public void addBase(long base, Vector args) { + } + public void addFixed(Boolean fixed, Vector args) { + } + public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + } + public void addIncremental(boolean incremental, Vector args) { + } + public void addMap(boolean map, Vector args) { + } + public void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + public String getCommandFileSwitch(String commandFile) { + return null; + } + public File[] getLibraryPath() { + return new File[0]; + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return new String[0]; + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + String[] baseNames = super.getOutputFileNames(baseName, versionInfo); + if (outputPrefix.length() > 0) { + for(int i = 0; i < baseNames.length; i++) { + baseNames[i] = outputPrefix + baseNames[i]; + } + } + return baseNames; + } + public String[] getOutputFileSwitch(String outputFile) { + return GccProcessor.getOutputFileSwitch("rvs", outputFile); + } + public boolean isCaseSensitive() { + return true; + } + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + // + // if there is an existing library then + // we must delete it before executing "ar" + if (outputFile.exists()) { + if (!outputFile.delete()) { + throw new BuildException("Unable to delete " + + outputFile.getAbsolutePath()); + } + } + // + // delegate to CommandLineLinker + // + super.link(task, outputFile, sourceFiles, config); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java new file mode 100644 index 0000000..75ddcc7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java @@ -0,0 +1,339 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Abstract adapter for ld-like linkers + * + * @author Curt Arnold + */ +public abstract class AbstractLdLinker extends CommandLineLinker { + private String outputPrefix; + protected AbstractLdLinker(String command, String identifierArg, + String[] extensions, String[] ignoredExtensions, + String outputPrefix, String outputSuffix, boolean isLibtool, + AbstractLdLinker libtoolLinker) { + super(command, identifierArg, extensions, ignoredExtensions, + outputSuffix, isLibtool, libtoolLinker); + this.outputPrefix = outputPrefix; + } + public void addBase(long base, Vector args) { + if (base >= 0) { + args.addElement("--image-base"); + args.addElement(Long.toHexString(base)); + } + } + public void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (debug) { + args.addElement("-g"); + } + if (isDarwin()) { + if (linkType.isPluginModule()) { + args.addElement("-bundle"); + } else { + if (linkType.isSharedLibrary()) { + args.addElement("-prebind"); + args.addElement("-dynamiclib"); + } + } + } else { + if (linkType.isStaticRuntime()) { + args.addElement("-static"); + } + if (linkType.isPluginModule()) { + args.addElement("-shared"); + } else { + if (linkType.isSharedLibrary()) { + args.addElement("-shared"); + } + } + } + } + public void addIncremental(boolean incremental, Vector args) { + if (incremental) { + args.addElement("-i"); + } + } + protected int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + public String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + Vector libnames = new Vector(); + super.addLibrarySets(task, libsets, preargs, midargs, endargs); + LibraryTypeEnum previousLibraryType = null; + for (int i = 0; i < libsets.length; i++) { + LibrarySet set = libsets[i]; + File libdir = set.getDir(null); + String[] libs = set.getLibs(); + if (libdir != null) { + String relPath = libdir.getAbsolutePath(); + File outputFile = task.getOutfile(); + if (outputFile != null && outputFile.getParentFile() != null) { + relPath = CUtil.getRelativePath( + outputFile.getParentFile().getAbsolutePath(), libdir); + } + if (set.getType() != null && + "framework".equals(set.getType().getValue()) && + isDarwin()) { + endargs.addElement("-F" + relPath); + } else { + endargs.addElement("-L" + relPath); + } + } + // + // if there has been a change of library type + // + if (set.getType() != previousLibraryType) { + if (set.getType() != null && "static".equals(set.getType().getValue())) { + endargs.addElement(getStaticLibFlag()); + previousLibraryType = set.getType(); + } else { + if (set.getType() == null || + !"framework".equals(set.getType().getValue()) || + !isDarwin()) { + endargs.addElement(getDynamicLibFlag()); + previousLibraryType = set.getType(); + } + } + } + StringBuffer buf = new StringBuffer("-l"); + if (set.getType() != null && + "framework".equals(set.getType().getValue()) && + isDarwin()) { + buf.setLength(0); + buf.append("-framework "); + } + int initialLength = buf.length(); + for (int j = 0; j < libs.length; j++) { + // + // reset the buffer to just "-l" + // + buf.setLength(initialLength); + // + // add the library name + buf.append(libs[j]); + libnames.addElement(libs[j]); + // + // add the argument to the list + endargs.addElement(buf.toString()); + } + } + String rc[] = new String[libnames.size()]; + for (int i = 0; i < libnames.size(); i++) { + rc[i] = (String) libnames.elementAt(i); + } + return rc; + } + public void addMap(boolean map, Vector args) { + if (map) { + args.addElement("-M"); + } + } + public void addStack(int stack, Vector args) { + if (stack > 0) { + args.addElement("--stack"); + args.addElement(Integer.toString(stack)); + } + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + if (entry != null) { + args.addElement("-e"); + args.addElement(entry); + } + } + + public String getCommandFileSwitch(String commandFile) { + throw new IllegalStateException("ld does not support command files"); + } + /** + * Returns library path. + * + */ + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("LIB", ":"); + } + public String getLibraryKey(File libfile) { + String libname = libfile.getName(); + int lastDot = libname.lastIndexOf('.'); + if (lastDot >= 0) { + return libname.substring(0, lastDot); + } + return libname; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + return new File[0]; + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + int patternCount = libnames.length; + if (libType == null) { + patternCount *= 2; + } + String[] patterns = new String[patternCount]; + int offset = 0; + if (libType == null || "static".equals(libType.getValue())) { + offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + } + if (libType != null && "framework".equals(libType.getValue()) && isDarwin()) { + for(int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(libnames[i]); + buf.append(".framework/"); + buf.append(libnames[i]); + patterns[offset++] = buf.toString(); + } + } else { + if (libType == null || !"static".equals(libType.getValue())) { + if (isHPUX()) { + offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns, + offset); + } else { + offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns, + offset); + } + } + } + return patterns; + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + String[] baseNames = super.getOutputFileNames(baseName, versionInfo); + if (outputPrefix.length() > 0) { + for(int i = 0; i < baseNames.length; i++) { + baseNames[i] = outputPrefix + baseNames[i]; + } + } + return baseNames; + } + public String[] getOutputFileSwitch(String outputFile) { + return GccProcessor.getOutputFileSwitch("-o", outputFile); + } + + public boolean isCaseSensitive() { + return true; + } + protected boolean isHPUX() { + String osname = System.getProperty("os.name").toLowerCase(); + if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) { + return true; + } + return false; + } + /** + * Prepares argument list for exec command. Will return null if command + * line would exceed allowable command line buffer. + * + * @param outputFile + * linker output file + * @param sourceFiles + * linker input files (.obj, .o, .res) + * @param config + * linker configuration + * @return arguments for runTask + */ + public String[] prepareArguments(CCTask task, String outputDir, + String outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) { + // + // need to suppress sources that correspond to + // library set entries since they are already + // in the argument list + String[] libnames = config.getLibraryNames(); + if (libnames == null || libnames.length == 0) { + return super.prepareArguments(task, outputDir, outputFile, + sourceFiles, config); + } + // + // + // null out any sources that correspond to library names + // + String[] localSources = (String[]) sourceFiles.clone(); + int extra = 0; + for (int i = 0; i < libnames.length; i++) { + String libname = libnames[i]; + for (int j = 0; j < localSources.length; j++) { + if (localSources[j] != null + && localSources[j].indexOf(libname) > 0 + && localSources[j].indexOf("lib") > 0) { + String filename = new File(localSources[j]).getName(); + if (filename.startsWith("lib") + && filename.substring(3).startsWith(libname)) { + String extension = filename + .substring(libname.length() + 3); + if (extension.equals(".a") || extension.equals(".so") + || extension.equals(".sl")) { + localSources[j] = null; + extra++; + } + } + } + } + } + if (extra == 0) { + return super.prepareArguments(task, outputDir, outputFile, + sourceFiles, config); + } + String[] finalSources = new String[localSources.length - extra]; + int index = 0; + for (int i = 0; i < localSources.length; i++) { + if (localSources[i] != null) { + finalSources[index++] = localSources[i]; + } + } + return super.prepareArguments(task, outputDir, outputFile, + finalSources, config); + } + + protected String getDynamicLibFlag() { + return "-Bdynamic"; + } + + protected String getStaticLibFlag() { + return "-Bstatic"; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java new file mode 100644 index 0000000..999ccf7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java @@ -0,0 +1,242 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.FortranParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +/** + * Adapter for the GCC C/C++ compiler + * + * @author Adam Murdoch + */ +public final class GccCCompiler extends GccCompatibleCCompiler { + private final static String[] sourceExtensions = new String[]{".c", /* C */ + ".cc", /* C++ */ + ".cpp", /* C++ */ + ".cxx", /* C++ */ + ".c++", /* C++ */ + ".i", /* preprocessed C */ + ".ii", /* preprocessed C++ */ + ".f", /* FORTRAN */ + ".for", /* FORTRAN */ + ".m", /* Objective-C */ + ".mm", /* Objected-C++ */ + ".s" /* Assembly */ + }; + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private static final GccCCompiler cppInstance = new GccCCompiler("c++", + sourceExtensions, headerExtensions, false, + new GccCCompiler("c++", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + private static final GccCCompiler g77Instance = new GccCCompiler("g77", + sourceExtensions, headerExtensions, false, + new GccCCompiler("g77", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + private static final GccCCompiler gppInstance = new GccCCompiler("g++", + sourceExtensions, headerExtensions, false, + new GccCCompiler("g++", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + private static final GccCCompiler instance = new GccCCompiler("gcc", + sourceExtensions, headerExtensions, false, + new GccCCompiler("gcc", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + /** + * Gets c++ adapter + */ + public static GccCCompiler getCppInstance() { + return cppInstance; + } + /** + * Gets g77 adapter + */ + public static GccCCompiler getG77Instance() { + return g77Instance; + } + /** + * Gets gpp adapter + */ + public static GccCCompiler getGppInstance() { + return gppInstance; + } + /** + * Gets gcc adapter + */ + public static GccCCompiler getInstance() { + return instance; + } + private String identifier; + private File[] includePath; + private boolean isPICMeaningful = true; + /** + * Private constructor. Use GccCCompiler.getInstance() to get singleton + * instance of this class. + */ + private GccCCompiler(String command, String[] sourceExtensions, + String[] headerExtensions, boolean isLibtool, + GccCCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super(command, null, sourceExtensions, headerExtensions, isLibtool, + libtoolCompiler, newEnvironment, env); + isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0; + } + public void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + super.addImpliedArgs(args, debug, multithreaded, + exceptions, linkType, rtti, optimization); + if (isPICMeaningful && linkType.isSharedLibrary()) { + args.addElement("-fPIC"); + } + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new GccCCompiler(getCommand(), this.getSourceExtensions(), + this.getHeaderExtensions(), this.getLibtool(), + (GccCCompiler) this.getLibtoolCompiler(), newEnvironment, + env); + } + return this; + } + /** + * Create parser to determine dependencies. + * + * Will create appropriate parser (C++, FORTRAN) based on file extension. + * + */ + protected Parser createParser(File source) { + if (source != null) { + String sourceName = source.getName(); + int lastDot = sourceName.lastIndexOf('.'); + if (lastDot >= 0 && lastDot + 1 < sourceName.length()) { + char afterDot = sourceName.charAt(lastDot + 1); + if (afterDot == 'f' || afterDot == 'F') { + return new FortranParser(); + } + } + } + return new CParser(); + } + public File[] getEnvironmentIncludePath() { + if (includePath == null) { + // + // construct default include path from machine id and version id + // + String[] defaultInclude = new String[1]; + StringBuffer buf = new StringBuffer("/lib/"); + buf.append(GccProcessor.getMachine()); + buf.append('/'); + buf.append(GccProcessor.getVersion()); + buf.append("/include"); + defaultInclude[0] = buf.toString(); + // + // read specs file and look for -istart and -idirafter + // + String[] specs = GccProcessor.getSpecs(); + String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:", + new String[]{"-isystem ", "-idirafter "}); + // + // if no entries were found, then use a default path + // + if (optionValues[0].length == 0 && optionValues[1].length == 0) { + optionValues[0] = new String[]{"/usr/local/include", + "/usr/include", "/usr/include/win32api"}; + } + // + // remove mingw entries. + // For MinGW compiles this will mean the + // location of the sys includes will be + // wrong in dependencies.xml + // but that should have no significant effect + for (int i = 0; i < optionValues.length; i++) { + for (int j = 0; j < optionValues[i].length; j++) { + if (optionValues[i][j].indexOf("mingw") > 0) { + optionValues[i][j] = null; + } + } + } + // + // if cygwin then + // we have to prepend location of gcc32 + // and .. to start of absolute filenames to + // have something that will exist in the + // windows filesystem + if (GccProcessor.isCygwin()) { + GccProcessor.convertCygwinFilenames(optionValues[0]); + GccProcessor.convertCygwinFilenames(optionValues[1]); + GccProcessor.convertCygwinFilenames(defaultInclude); + } + int count = CUtil.checkDirectoryArray(optionValues[0]); + count += CUtil.checkDirectoryArray(optionValues[1]); + count += CUtil.checkDirectoryArray(defaultInclude); + includePath = new File[count]; + int index = 0; + for (int i = 0; i < optionValues.length; i++) { + for (int j = 0; j < optionValues[i].length; j++) { + if (optionValues[i][j] != null) { + includePath[index++] = new File(optionValues[i][j]); + } + } + } + for (int i = 0; i < defaultInclude.length; i++) { + if (defaultInclude[i] != null) { + includePath[index++] = new File(defaultInclude[i]); + } + } + } + return (File[]) includePath.clone(); + } + public String getIdentifier() throws BuildException { + if (identifier == null) { + StringBuffer buf; + if (getLibtool()) { + buf = new StringBuffer("libtool "); + } else { + buf = new StringBuffer(' '); + } + buf.append(getCommand()); + buf.append(' '); + buf.append(GccProcessor.getVersion()); + buf.append(' '); + buf.append(GccProcessor.getMachine()); + identifier = buf.toString(); + } + return identifier; + } + public Linker getLinker(LinkType linkType) { + return GccLinker.getInstance().getLinker(linkType); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java new file mode 100644 index 0000000..0485fba --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java @@ -0,0 +1,146 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +/** + * Abstract base class for compilers that attempt to be command line compatible + * with GCC + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public abstract class GccCompatibleCCompiler extends CommandLineCCompiler { + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private final static String[] sourceExtensions = new String[]{".c", ".cc", + ".cpp", ".cxx", ".c++", ".i", ".f", ".for"}; + /** + * Private constructor. Use GccCCompiler.getInstance() to get singleton + * instance of this class. + */ + protected GccCompatibleCCompiler(String command, String identifierArg, + boolean libtool, GccCompatibleCCompiler libtoolCompiler, + boolean newEnvironment, Environment env) { + super(command, identifierArg, sourceExtensions, headerExtensions, + libtool ? ".fo" : ".o", libtool, libtoolCompiler, + newEnvironment, env); + } + /** + * Private constructor. Use GccCCompiler.getInstance() to get singleton + * instance of this class. + */ + protected GccCompatibleCCompiler(String command, String identifierArg, + String[] sourceExtensions, String[] headerExtensions, + boolean libtool, GccCompatibleCCompiler libtoolCompiler, + boolean newEnvironment, Environment env) { + super(command, identifierArg, sourceExtensions, headerExtensions, + libtool ? ".fo" : ".o", libtool, libtoolCompiler, + newEnvironment, env); + } + public void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + // + // -fPIC is too much trouble + // users have to manually add it for + // operating systems that make sense + // + args.addElement("-c"); + if (debug) { + args.addElement("-g"); + } else { + if (optimization != null) { + if (optimization.isSize()) { + args.addElement("-Os"); + } else if (optimization.isSpeed()) { + if ("full".equals(optimization.getValue())) { + args.addElement("-O2"); + } else { + if ("speed".equals(optimization.getValue())) { + args.addElement("-O1"); + } else { + args.addElement("-O3"); + } + } + } + } + } + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + if (rtti != null && !rtti.booleanValue()) { + args.addElement("-fno-rtti"); + } + + } + /** + * Adds an include path to the command. + */ + public void addIncludePath(String path, Vector cmd) { + cmd.addElement("-I" + path); + } + public void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("-w"); + break; + case 5 : + args.addElement("-Werror"); + /* nobreak */ + case 4 : + args.addElement("-W"); + /* nobreak */ + case 3 : + args.addElement("-Wall"); + break; + } + } + public void getDefineSwitch(StringBuffer buffer, String define, String value) { + buffer.append("-D"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ":"); + } + public String getIncludeDirSwitch(String includeDir) { + return "-I" + includeDir; + } + public void getUndefineSwitch(StringBuffer buffer, String define) { + buffer.append("-U"); + buffer.append(define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java new file mode 100644 index 0000000..0c6ae4b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java @@ -0,0 +1,41 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +/** + * Adapter for the 'ar' archiver + * + * @author Adam Murdoch + */ +public final class GccLibrarian extends AbstractArLibrarian { + private static String[] objFileExtensions = new String[]{".o"}; + private static GccLibrarian instance = new GccLibrarian("ar", + objFileExtensions, false, new GccLibrarian("ar", objFileExtensions, + true, null)); + public static GccLibrarian getInstance() { + return instance; + } + private GccLibrarian(String command, String[] inputExtensions, + boolean isLibtool, GccLibrarian libtoolLibrarian) { + super(command, "V", inputExtensions, new String[0], "lib", ".a", + isLibtool, libtoolLibrarian); + } + public Linker getLinker(LinkType type) { + return GccLinker.getInstance().getLinker(type); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java new file mode 100644 index 0000000..c4720c8 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccLinker.java @@ -0,0 +1,210 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +/** + * Adapter for the GCC linker + * + * @author Adam Murdoch + */ +public class GccLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static String[] linkerOptions = new String[]{"-bundle", + "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s", + "-static", "-shared", "-symbolic", "-Xlinker", + "--export-all-symbols", "-static-libgcc",}; + private static final GccLinker dllLinker = new GccLinker("gcc", objFiles, + discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles, + discardFiles, "lib", ".so", true, null)); + private static final GccLinker instance = new GccLinker("gcc", objFiles, + discardFiles, "", "", false, null); + private static final GccLinker machBundleLinker = new GccLinker("gcc", + objFiles, discardFiles, "lib", ".bundle", false, null); + private static final GccLinker machDllLinker = new GccLinker("gcc", + objFiles, discardFiles, "lib", ".dylib", false, null); + public static GccLinker getInstance() { + return instance; + } + private File[] libDirs; + protected GccLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) { + super(command, "-dumpversion", extensions, ignoredExtensions, + outputPrefix, outputSuffix, isLibtool, libtoolLinker); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + super.addImpliedArgs(debug, linkType, args); + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + } + /** + * Allows drived linker to decorate linker option. Override by GccLinker to + * prepend a "-Wl," to pass option to through gcc to linker. + * + * @param buf + * buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg + * linker argument + */ + public String decorateLinkerOption(StringBuffer buf, String arg) { + String decoratedArg = arg; + if (arg.length() > 1 && arg.charAt(0) == '-') { + switch (arg.charAt(1)) { + // + // passed automatically by GCC + // + case 'g' : + case 'f' : + case 'F' : + /* Darwin */ + case 'm' : + case 'O' : + case 'W' : + case 'l' : + case 'L' : + case 'u' : + case 'v' : + break; + default : + boolean known = false; + for (int i = 0; i < linkerOptions.length; i++) { + if (linkerOptions[i].equals(arg)) { + known = true; + break; + } + } + if (!known) { + buf.setLength(0); + buf.append("-Wl,"); + buf.append(arg); + decoratedArg = buf.toString(); + } + break; + } + } + return decoratedArg; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + // + // construct gcc lib path from machine and version + // + StringBuffer buf = new StringBuffer("/lib/gcc-lib/"); + buf.append(GccProcessor.getMachine()); + buf.append('/'); + buf.append(GccProcessor.getVersion()); + // + // build default path from gcc and system /lib and /lib/w32api + // + String[] impliedLibPath = new String[]{buf.toString(), + "/lib/w32api", "/lib"}; + // + // read gcc specs file for other library paths + // + String[] specs = GccProcessor.getSpecs(); + String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:", + new String[]{"%q"}); + String[] libpath; + if (libpaths[0].length > 0) { + libpath = new String[libpaths[0].length + 3]; + int i = 0; + for (; i < libpaths[0].length; i++) { + libpath[i] = libpaths[0][i]; + } + libpath[i++] = buf.toString(); + libpath[i++] = "/lib/w32api"; + libpath[i++] = "/lib"; + } else { + // + // if a failure to find any matches then + // use some default values for lib path entries + libpath = new String[]{"/usr/local/lib/mingw", + "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw", + "/usr/lib", buf.toString(), "/lib/w32api", "/lib"}; + } + for (int i = 0; i < libpath.length; i++) { + if (libpath[i].indexOf("mingw") >= 0) { + libpath[i] = null; + } + } + // + // if cygwin then + // we have to prepend location of gcc32 + // and .. to start of absolute filenames to + // have something that will exist in the + // windows filesystem + if (GccProcessor.isCygwin()) { + GccProcessor.convertCygwinFilenames(libpath); + } + // + // check that remaining entries are actual directories + // + int count = CUtil.checkDirectoryArray(libpath); + // + // populate return array with remaining entries + // + libDirs = new File[count]; + int index = 0; + for (int i = 0; i < libpath.length; i++) { + if (libpath[i] != null) { + libDirs[index++] = new File(libpath[i]); + } + } + } + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isPluginModule()) { + if (isDarwin()) { + return machBundleLinker; + } else { + return dllLinker; + } + } + if (type.isSharedLibrary()) { + if (isDarwin()) { + return machDllLinker; + } else { + return dllLinker; + } + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java new file mode 100644 index 0000000..988848d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java @@ -0,0 +1,299 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; +/** + * A add-in class for Gcc processors + * + * + */ +public class GccProcessor { + // the results from gcc -dumpmachine + private static String machine; + private static String[] specs; + // the results from gcc -dumpversion + private static String version; + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + /** + * Converts absolute Cygwin file or directory names to the corresponding + * Win32 name. + * + * @param names + * array of names, some elements may be null, will be changed in + * place. + */ + public static void convertCygwinFilenames(String[] names) { + if (names == null) { + throw new NullPointerException("names"); + } + File gccDir = CUtil.getExecutableLocation("gcc.exe"); + if (gccDir != null) { + String prefix = gccDir.getAbsolutePath() + "/.."; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + if (name != null && name.length() > 1 && name.charAt(0) == '/') { + buf.setLength(0); + buf.append(prefix); + buf.append(name); + names[i] = buf.toString(); + } + } + } + } + public static String[] getLibraryPatterns(String[] libnames) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length * 2]; + int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + if (isHPUX()) { + offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns, + offset); + } else { + offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns, + offset); + } + return patterns; + } + public static String getMachine() { + if (machine == null) { + String[] args = new String[]{"gcc", "-dumpmachine"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + machine = "nomachine"; + } else { + machine = cmdout[0]; + } + } + return machine; + } + public static String[] getOutputFileSwitch(String letter, String outputFile) { + StringBuffer buf = new StringBuffer(); + if (outputFile.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(outputFile.replace('\\', '/')); + buf.append('"'); + } else { + buf.append(outputFile.replace('\\', '/')); + } + String[] retval = new String[]{letter, buf.toString()}; + return retval; + } + /** + * Returns the contents of the gcc specs file. + * + * The implementation locates gcc.exe in the executable path and then + * builds a relative path name from the results of -dumpmachine and + * -dumpversion. Attempts to use gcc -dumpspecs to provide this information + * resulted in stalling on the Execute.run + * + * @return contents of the specs file + */ + public static String[] getSpecs() { + if (specs == null) { + File gccParent = CUtil.getExecutableLocation("gcc.exe"); + if (gccParent != null) { + // + // build a relative path like + // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs + // + StringBuffer buf = new StringBuffer("../lib/gcc-lib/"); + buf.append(getMachine()); + buf.append('/'); + buf.append(getVersion()); + buf.append("/specs"); + // + // resolve it relative to the location of gcc.exe + // + String relativePath = buf.toString(); + File specsFile = new File(gccParent, relativePath); + // + // found the specs file + // + try { + // + // read the lines in the file + // + BufferedReader reader = new BufferedReader(new FileReader( + specsFile)); + Vector lines = new Vector(100); + String line = reader.readLine(); + while (line != null) { + lines.addElement(line); + line = reader.readLine(); + } + specs = new String[lines.size()]; + lines.copyInto(specs); + } catch (IOException ex) { + } + } + } + if (specs == null) { + specs = new String[0]; + } + return specs; + } + public static String getVersion() { + if (version == null) { + String[] args = new String[]{"gcc", "-dumpversion"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + version = "noversion"; + } else { + version = cmdout[0]; + } + } + return version; + } + public static boolean isCaseSensitive() { + return true; + } + /** + * Determines if task is running with cygwin + * + * @return true if cygwin was detected + */ + public static boolean isCygwin() { + return getMachine().indexOf("cygwin") > 0; + } + private static boolean isHPUX() { + String osname = System.getProperty("os.name").toLowerCase(); + if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) { + return true; + } + return false; + } + /** + * + * Parses the results of the specs file for a specific processor and + * options + * + * @param specsContent + * Contents of specs file as returned from getSpecs + * @param specSectionStart + * start of spec section, for example "*cpp:" + * @param options + * command line switches such as "-istart" + */ + public static String[][] parseSpecs(String[] specsContent, + String specSectionStart, String[] options) { + if (specsContent == null) { + throw new NullPointerException("specsContent"); + } + if (specSectionStart == null) { + throw new NullPointerException("specSectionStart"); + } + if (options == null) { + throw new NullPointerException("option"); + } + String[][] optionValues = new String[options.length][]; + StringBuffer optionValue = new StringBuffer(40); + for (int i = 0; i < specsContent.length; i++) { + String specLine = specsContent[i]; + // + // if start of section then start paying attention + // + if (specLine.startsWith(specSectionStart)) { + Vector[] optionVectors = new Vector[options.length]; + for (int j = 0; j < options.length; j++) { + optionVectors[j] = new Vector(10); + } + // + // go to next line and examine contents + // and repeat until end of file + // + for (i++; i < specsContent.length; i++) { + specLine = specsContent[i]; + for (int j = 0; j < options.length; j++) { + int optionStart = specLine.indexOf(options[j]); + while (optionStart >= 0) { + optionValue.setLength(0); + // + // walk rest of line looking for first non + // whitespace + // and then next space + boolean hasNonBlank = false; + int k = optionStart + options[j].length(); + for (; k < specLine.length(); k++) { + // + // either a blank or a "}" (close of + // conditional) + // section will end the path + // + if (specLine.charAt(k) == ' ' + || specLine.charAt(k) == '}') { + if (hasNonBlank) { + break; + } + } else { + hasNonBlank = true; + optionValue.append(specLine.charAt(k)); + } + } + // + // transition back to whitespace + // value is over, add it to vector + if (hasNonBlank) { + optionVectors[j].addElement(optionValue + .toString()); + } + // + // find next occurance on line + // + optionStart = specLine.indexOf(options[j], k); + } + } + } + // + // copy vectors over to option arrays + // + for (int j = 0; j < options.length; j++) { + optionValues[j] = new String[optionVectors[j].size()]; + optionVectors[j].copyInto(optionValues[j]); + } + } + } + // + // fill in any missing option values with + // a zero-length string array + for (int i = 0; i < optionValues.length; i++) { + String[] zeroLenArray = new String[0]; + if (optionValues[i] == null) { + optionValues[i] = zeroLenArray; + } + } + return optionValues; + } + private GccProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java new file mode 100644 index 0000000..f3bc174 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GppLinker.java @@ -0,0 +1,203 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +/** + * Adapter for the g++ variant of the GCC linker + * + * @author Stephen M. Webb + */ +public class GppLinker extends AbstractLdLinker { + protected static final String[] discardFiles = new String[0]; + protected static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final GppLinker dllLinker = new GppLinker("gcc", objFiles, + discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles, + discardFiles, "lib", ".so", true, null)); + private final static String libPrefix = "libraries: ="; + protected static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static String[] linkerOptions = new String[]{"-bundle", "-dylib", + "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib", + "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"}; + private static final GppLinker instance = new GppLinker("gcc", objFiles, + discardFiles, "", "", false, null); + private static final GppLinker machDllLinker = new GppLinker("gcc", + objFiles, discardFiles, "lib", ".dylib", false, null); + private static final GppLinker machPluginLinker = new GppLinker("gcc", + objFiles, discardFiles, "lib", ".bundle", false, null); + public static GppLinker getInstance() { + return instance; + } + private File[] libDirs; + private String runtimeLibrary; + protected GppLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) { + super(command, "-dumpversion", extensions, ignoredExtensions, + outputPrefix, outputSuffix, isLibtool, libtoolLinker); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + super.addImpliedArgs(debug, linkType, args); + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + if (linkType.isStaticRuntime()) { + String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"}; + String[] cmdout = CaptureStreamHandler.run(cmdin); + if (cmdout.length > 0) { + runtimeLibrary = cmdout[0]; + } else { + runtimeLibrary = null; + } + } else { + runtimeLibrary = "-lstdc++"; + } + } + public String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + String[] rs = super.addLibrarySets(task, libsets, preargs, midargs, + endargs); + if (runtimeLibrary != null) { + endargs.addElement(runtimeLibrary); + } + return rs; + } + /** + * Allows drived linker to decorate linker option. Override by GppLinker to + * prepend a "-Wl," to pass option to through gcc to linker. + * + * @param buf + * buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg + * linker argument + */ + public String decorateLinkerOption(StringBuffer buf, String arg) { + String decoratedArg = arg; + if (arg.length() > 1 && arg.charAt(0) == '-') { + switch (arg.charAt(1)) { + // + // passed automatically by GCC + // + case 'g' : + case 'f' : + case 'F' : + /* Darwin */ + case 'm' : + case 'O' : + case 'W' : + case 'l' : + case 'L' : + case 'u' : + break; + default : + boolean known = false; + for (int i = 0; i < linkerOptions.length; i++) { + if (linkerOptions[i].equals(arg)) { + known = true; + break; + } + } + if (!known) { + buf.setLength(0); + buf.append("-Wl,"); + buf.append(arg); + decoratedArg = buf.toString(); + } + break; + } + } + return decoratedArg; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + Vector dirs = new Vector(); + // Ask GCC where it will look for its libraries. + String[] args = new String[]{"g++", "-print-search-dirs"}; + String[] cmdout = CaptureStreamHandler.run(args); + for (int i = 0; i < cmdout.length; ++i) { + int prefixIndex = cmdout[i].indexOf(libPrefix); + if (prefixIndex >= 0) { + // Special case DOS-type GCCs like MinGW or Cygwin + int s = prefixIndex + libPrefix.length(); + int t = cmdout[i].indexOf(';', s); + while (t > 0) { + dirs.addElement(cmdout[i].substring(s, t)); + s = t + 1; + t = cmdout[i].indexOf(';', s); + } + dirs.addElement(cmdout[i].substring(s)); + ++i; + for (; i < cmdout.length; ++i) { + dirs.addElement(cmdout[i]); + } + } + } + // Eliminate all but actual directories. + String[] libpath = new String[dirs.size()]; + dirs.copyInto(libpath); + int count = CUtil.checkDirectoryArray(libpath); + // Build return array. + libDirs = new File[count]; + int index = 0; + for (int i = 0; i < libpath.length; ++i) { + if (libpath[i] != null) { + libDirs[index++] = new File(libpath[i]); + } + } + } + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isPluginModule()) { + if (GccProcessor.getMachine().indexOf("darwin") >= 0) { + return machPluginLinker; + } else { + return dllLinker; + } + } + if (type.isSharedLibrary()) { + if (GccProcessor.getMachine().indexOf("darwin") >= 0) { + return machDllLinker; + } else { + return dllLinker; + } + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java new file mode 100644 index 0000000..2104e34 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/LdLinker.java @@ -0,0 +1,57 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +/** + * Adapter for the 'ld' linker + * + * @author Curt Arnold + */ +public final class LdLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final LdLinker dllLinker = new LdLinker("ld", objFiles, + discardFiles, "lib", ".so", false, new LdLinker("ld", objFiles, + discardFiles, "lib", ".so", true, null)); + private static final LdLinker instance = new LdLinker("ld", objFiles, + discardFiles, "", "", false, null); + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + public static LdLinker getInstance() { + return instance; + } + private File[] libDirs; + private LdLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) { + super(command, "-version", extensions, ignoredExtensions, outputPrefix, + outputSuffix, isLibtool, libtoolLinker); + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java new file mode 100644 index 0000000..a617024 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/WindresResourceCompiler.java @@ -0,0 +1,121 @@ +/* + * + * Copyright 2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the GNU windres resource compiler. + * + * @author Curt Arnold + */ +public final class WindresResourceCompiler extends CommandLineCompiler { + private static final WindresResourceCompiler instance = new WindresResourceCompiler( + false, null); + public static WindresResourceCompiler getInstance() { + return instance; + } + private WindresResourceCompiler(boolean newEnvironment, Environment env) { + super("windres", null, new String[]{".rc"}, new String[]{".h", ".hpp", + ".inl"}, ".o", false, null, newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + if (debug) { + args.addElement("-D_DEBUG"); + } else { + args.addElement("-DNDEBUG"); + } + } + protected void addWarningSwitch(Vector args, int level) { + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new WindresResourceCompiler(newEnvironment, env); + } + return this; + } + /** + * The include parser for C will work just fine, but we didn't want to + * inherit from CommandLineCCompiler + */ + protected Parser createParser(File source) { + return new CParser(); + } + protected int getArgumentCountPerInputFile() { + return 2; + } + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("-D"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + protected File[] getEnvironmentIncludePath() { + return new File[0]; + } + protected String getIncludeDirSwitch(String includeDir) { + return "-I" + includeDir; + } + protected String getInputFileArgument(File outputDir, String filename, + int index) { + if (index == 0) { + String outputFileName = getOutputFileNames(filename, null)[0]; + return "-o" + outputFileName; + } + return filename; + } + public Linker getLinker(LinkType type) { + return GccLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } + protected int getMaximumInputFilesPerCommand() { + return 1; + } + protected int getTotalArgumentLengthForInputFile(File outputDir, + String inputFile) { + String arg1 = getInputFileArgument(outputDir, inputFile, 0); + String arg2 = getInputFileArgument(outputDir, inputFile, 1); + return arg1.length() + arg2.length() + 2; + } + protected void getUndefineSwitch(StringBuffer buffer, String define) { + buffer.append("-U"); + buffer.append(define); + } + public String getIdentifier() { + return "GNU windres"; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java new file mode 100644 index 0000000..86a8ac7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java @@ -0,0 +1,272 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross; +import java.io.File; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.CompilerParam; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.FortranParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +/** + * Adapter for the GCC C/C++ compiler + * + * @author Adam Murdoch + */ +public final class GccCCompiler extends GccCompatibleCCompiler { + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private final static String[] sourceExtensions = new String[]{".c", /* C */ + ".cc", /* C++ */ + ".cpp", /* C++ */ + ".cxx", /* C++ */ + ".c++", /* C++ */ + ".i", /* preprocessed C */ + ".ii", /* preprocessed C++ */ + ".f", /* FORTRAN */ + ".for", /* FORTRAN */ + ".m", /* Objective-C */ + ".mm", /* Objected-C++ */ + ".s" /* Assembly */ + }; + private static final GccCCompiler cppInstance = new GccCCompiler("c++", + sourceExtensions, headerExtensions, false, + new GccCCompiler("c++", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + private static final GccCCompiler g77Instance = new GccCCompiler("g77", + sourceExtensions, headerExtensions, false, + new GccCCompiler("g77", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + private static final GccCCompiler gppInstance = new GccCCompiler("g++", + sourceExtensions, headerExtensions, false, + new GccCCompiler("g++", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + private static final GccCCompiler instance = new GccCCompiler("gcc", + sourceExtensions, headerExtensions, false, + new GccCCompiler("gcc", sourceExtensions, headerExtensions, true, + null, false, null), false, null); + /** + * Gets c++ adapter + */ + public static GccCCompiler getCppInstance() { + return cppInstance; + } + /** + * Gets g77 adapter + */ + public static GccCCompiler getG77Instance() { + return g77Instance; + } + /** + * Gets gpp adapter + */ + public static GccCCompiler getGppInstance() { + return gppInstance; + } + /** + * Gets gcc adapter + */ + public static GccCCompiler getInstance() { + return instance; + } + private String identifier; + private File[] includePath; + private boolean isPICMeaningful = true; + /** + * Private constructor. Use GccCCompiler.getInstance() to get singleton + * instance of this class. + */ + private GccCCompiler(String command, String[] sourceExtensions, + String[] headerExtensions, boolean isLibtool, + GccCCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super(command, null, sourceExtensions, headerExtensions, isLibtool, + libtoolCompiler, newEnvironment, env); + isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0; + } + public void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + super.addImpliedArgs(args, debug, multithreaded, + exceptions, linkType, rtti, optimization); + if (isPICMeaningful && linkType.isSharedLibrary()) { + args.addElement("-fPIC"); + } + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new GccCCompiler(getCommand(), this.getSourceExtensions(), + this.getHeaderExtensions(), this.getLibtool(), + (GccCCompiler) this.getLibtoolCompiler(), newEnvironment, + env); + } + return this; + } + protected Object clone() throws CloneNotSupportedException { + GccCCompiler clone = (GccCCompiler) super.clone(); + return clone; + } + public void compile(CCTask task, File outputDir, String[] sourceFiles, + String[] args, String[] endArgs, boolean relentless, + CommandLineCompilerConfiguration config, ProgressMonitor monitor) + throws BuildException { + try { + GccCCompiler clone = (GccCCompiler) this.clone(); + CompilerParam param = config.getParam("target"); + if (param != null) + clone.setCommand(param.getValue() + "-" + this.getCommand()); + clone.supercompile(task, outputDir, sourceFiles, args, endArgs, + relentless, config, monitor); + } catch (CloneNotSupportedException e) { + supercompile(task, outputDir, sourceFiles, args, endArgs, + relentless, config, monitor); + } + } + /** + * Create parser to determine dependencies. + * + * Will create appropriate parser (C++, FORTRAN) based on file extension. + * + */ + protected Parser createParser(File source) { + if (source != null) { + String sourceName = source.getName(); + int lastDot = sourceName.lastIndexOf('.'); + if (lastDot >= 0 && lastDot + 1 < sourceName.length()) { + char afterDot = sourceName.charAt(lastDot + 1); + if (afterDot == 'f' || afterDot == 'F') { + return new FortranParser(); + } + } + } + return new CParser(); + } + public File[] getEnvironmentIncludePath() { + if (includePath == null) { + // + // construct default include path from machine id and version id + // + String[] defaultInclude = new String[1]; + StringBuffer buf = new StringBuffer("/lib/"); + buf.append(GccProcessor.getMachine()); + buf.append('/'); + buf.append(GccProcessor.getVersion()); + buf.append("/include"); + defaultInclude[0] = buf.toString(); + // + // read specs file and look for -istart and -idirafter + // + String[] specs = GccProcessor.getSpecs(); + String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:", + new String[]{"-isystem ", "-idirafter "}); + // + // if no entries were found, then use a default path + // + if (optionValues[0].length == 0 && optionValues[1].length == 0) { + optionValues[0] = new String[]{"/usr/local/include", + "/usr/include", "/usr/include/win32api"}; + } + // + // remove mingw entries. + // For MinGW compiles this will mean the + // location of the sys includes will be + // wrong in dependencies.xml + // but that should have no significant effect + for (int i = 0; i < optionValues.length; i++) { + for (int j = 0; j < optionValues[i].length; j++) { + if (optionValues[i][j].indexOf("mingw") > 0) { + optionValues[i][j] = null; + } + } + } + // + // if cygwin then + // we have to prepend location of gcc32 + // and .. to start of absolute filenames to + // have something that will exist in the + // windows filesystem + if (GccProcessor.isCygwin()) { + GccProcessor.convertCygwinFilenames(optionValues[0]); + GccProcessor.convertCygwinFilenames(optionValues[1]); + GccProcessor.convertCygwinFilenames(defaultInclude); + } + int count = CUtil.checkDirectoryArray(optionValues[0]); + count += CUtil.checkDirectoryArray(optionValues[1]); + count += CUtil.checkDirectoryArray(defaultInclude); + includePath = new File[count]; + int index = 0; + for (int i = 0; i < optionValues.length; i++) { + for (int j = 0; j < optionValues[i].length; j++) { + if (optionValues[i][j] != null) { + includePath[index++] = new File(optionValues[i][j]); + } + } + } + for (int i = 0; i < defaultInclude.length; i++) { + if (defaultInclude[i] != null) { + includePath[index++] = new File(defaultInclude[i]); + } + } + } + return (File[]) includePath.clone(); + } + public String getIdentifier() throws BuildException { + if (identifier == null) { + StringBuffer buf; + if (getLibtool()) { + buf = new StringBuffer("libtool "); + } else { + buf = new StringBuffer(' '); + } + buf.append(getCommand()); + buf.append(' '); + buf.append(GccProcessor.getVersion()); + buf.append(' '); + buf.append(GccProcessor.getMachine()); + identifier = buf.toString(); + } + return identifier; + } + public Linker getLinker(LinkType linkType) { + return GccLinker.getInstance().getLinker(linkType); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + private void supercompile(CCTask task, File outputDir, + String[] sourceFiles, String[] args, String[] endArgs, + boolean relentless, CommandLineCompilerConfiguration config, + ProgressMonitor monitor) throws BuildException { + super.compile(task, outputDir, sourceFiles, args, endArgs, relentless, + config, monitor); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java new file mode 100644 index 0000000..c9d28d9 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java @@ -0,0 +1,69 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.LinkerParam; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractArLibrarian; + +import org.apache.tools.ant.BuildException; +/** + * Adapter for the 'ar' archiver + * + * @author Adam Murdoch + */ +public final class GccLibrarian extends AbstractArLibrarian { + private static String[] objFileExtensions = new String[]{".o"}; + private static GccLibrarian instance = new GccLibrarian("ar", + objFileExtensions, false, new GccLibrarian("ar", objFileExtensions, + true, null)); + public static GccLibrarian getInstance() { + return instance; + } + private GccLibrarian(String command, String[] inputExtensions, + boolean isLibtool, GccLibrarian libtoolLibrarian) { + super(command, "V", inputExtensions, new String[0], "lib", ".a", + isLibtool, libtoolLibrarian); + } + protected Object clone() throws CloneNotSupportedException { + GccLibrarian clone = (GccLibrarian) super.clone(); + return clone; + } + public Linker getLinker(LinkType type) { + return GccLinker.getInstance().getLinker(type); + } + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + try { + GccLibrarian clone = (GccLibrarian) this.clone(); + LinkerParam param = config.getParam("target"); + if (param != null) + clone.setCommand(param.getValue() + "-" + this.getCommand()); + clone.superlink(task, outputFile, sourceFiles, config); + } catch (CloneNotSupportedException e) { + superlink(task, outputFile, sourceFiles, config); + } + } + private void superlink(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + super.link(task, outputFile, sourceFiles, config); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java new file mode 100644 index 0000000..4347211 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java @@ -0,0 +1,234 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross; +import java.io.File; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.LinkerParam; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +import org.apache.tools.ant.BuildException; +/** + * Adapter for the GCC linker + * + * @author Adam Murdoch + */ +public class GccLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final GccLinker dllLinker = new GccLinker("gcc", objFiles, + discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles, + discardFiles, "lib", ".so", true, null)); + private static final GccLinker instance = new GccLinker("gcc", objFiles, + discardFiles, "", "", false, null); + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static String[] linkerOptions = new String[]{"-bundle", + "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s", + "-static", "-shared", "-symbolic", "-Xlinker", + "--export-all-symbols", "-static-libgcc",}; + private static final GccLinker machBundleLinker = new GccLinker("gcc", + objFiles, discardFiles, "lib", ".bundle", false, null); + private static final GccLinker machDllLinker = new GccLinker("gcc", + objFiles, discardFiles, "lib", ".dylib", false, null); + public static GccLinker getInstance() { + return instance; + } + private File[] libDirs; + protected GccLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) { + super(command, "-dumpversion", extensions, ignoredExtensions, + outputPrefix, outputSuffix, isLibtool, libtoolLinker); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + super.addImpliedArgs(debug, linkType, args); + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + } + protected Object clone() throws CloneNotSupportedException { + GccLinker clone = (GccLinker) super.clone(); + return clone; + } + /** + * Allows drived linker to decorate linker option. Override by GccLinker to + * prepend a "-Wl," to pass option to through gcc to linker. + * + * @param buf + * buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg + * linker argument + */ + public String decorateLinkerOption(StringBuffer buf, String arg) { + String decoratedArg = arg; + if (arg.length() > 1 && arg.charAt(0) == '-') { + switch (arg.charAt(1)) { + // + // passed automatically by GCC + // + case 'g' : + case 'f' : + case 'F' : + /* Darwin */ + case 'm' : + case 'O' : + case 'W' : + case 'l' : + case 'L' : + case 'u' : + case 'v' : + break; + default : + boolean known = false; + for (int i = 0; i < linkerOptions.length; i++) { + if (linkerOptions[i].equals(arg)) { + known = true; + break; + } + } + if (!known) { + buf.setLength(0); + buf.append("-Wl,"); + buf.append(arg); + decoratedArg = buf.toString(); + } + break; + } + } + return decoratedArg; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + // + // construct gcc lib path from machine and version + // + StringBuffer buf = new StringBuffer("/lib/gcc-lib/"); + buf.append(GccProcessor.getMachine()); + buf.append('/'); + buf.append(GccProcessor.getVersion()); + // + // build default path from gcc and system /lib and /lib/w32api + // + String[] impliedLibPath = new String[]{buf.toString(), + "/lib/w32api", "/lib"}; + // + // read gcc specs file for other library paths + // + String[] specs = GccProcessor.getSpecs(); + String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:", + new String[]{"%q"}); + String[] libpath; + if (libpaths[0].length > 0) { + libpath = new String[libpaths[0].length + 3]; + int i = 0; + for (; i < libpaths[0].length; i++) { + libpath[i] = libpaths[0][i]; + } + libpath[i++] = buf.toString(); + libpath[i++] = "/lib/w32api"; + libpath[i++] = "/lib"; + } else { + // + // if a failure to find any matches then + // use some default values for lib path entries + libpath = new String[]{"/usr/local/lib/mingw", + "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw", + "/usr/lib", buf.toString(), "/lib/w32api", "/lib"}; + } + for (int i = 0; i < libpath.length; i++) { + if (libpath[i].indexOf("mingw") >= 0) { + libpath[i] = null; + } + } + // + // if cygwin then + // we have to prepend location of gcc32 + // and .. to start of absolute filenames to + // have something that will exist in the + // windows filesystem + if (GccProcessor.isCygwin()) { + GccProcessor.convertCygwinFilenames(libpath); + } + // + // check that remaining entries are actual directories + // + int count = CUtil.checkDirectoryArray(libpath); + // + // populate return array with remaining entries + // + libDirs = new File[count]; + int index = 0; + for (int i = 0; i < libpath.length; i++) { + if (libpath[i] != null) { + libDirs[index++] = new File(libpath[i]); + } + } + } + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isPluginModule()) { + if (isDarwin()) { + return machBundleLinker; + } else { + return dllLinker; + } + } + if (type.isSharedLibrary()) { + if (isDarwin()) { + return machDllLinker; + } else { + return dllLinker; + } + } + return instance; + } + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + try { + GccLinker clone = (GccLinker) this.clone(); + LinkerParam param = config.getParam("target"); + if (param != null) + clone.setCommand(param.getValue() + "-" + this.getCommand()); + clone.superlink(task, outputFile, sourceFiles, config); + } catch (CloneNotSupportedException e) { + superlink(task, outputFile, sourceFiles, config); + } + } + private void superlink(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + super.link(task, outputFile, sourceFiles, config); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java new file mode 100644 index 0000000..728cd47 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java @@ -0,0 +1,288 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; + +/** + * A add-in class for Gcc processors + * + * + */ +public class GccProcessor { + // the results from gcc -dumpmachine + private static String machine; + private static String[] specs; + // the results from gcc -dumpversion + private static String version; + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + /** + * Converts absolute Cygwin file or directory names to the corresponding + * Win32 name. + * + * @param names + * array of names, some elements may be null, will be changed in + * place. + */ + public static void convertCygwinFilenames(String[] names) { + if (names == null) { + throw new NullPointerException("names"); + } + File gccDir = CUtil.getExecutableLocation("gcc.exe"); + if (gccDir != null) { + String prefix = gccDir.getAbsolutePath() + "/.."; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + if (name != null && name.length() > 1 && name.charAt(0) == '/') { + buf.setLength(0); + buf.append(prefix); + buf.append(name); + names[i] = buf.toString(); + } + } + } + } + + public static String getMachine() { + if (machine == null) { + String[] args = new String[]{"gcc", "-dumpmachine"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + machine = "nomachine"; + } else { + machine = cmdout[0]; + } + } + return machine; + } + public static String[] getOutputFileSwitch(String letter, String outputFile) { + StringBuffer buf = new StringBuffer(); + if (outputFile.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(outputFile.replace('\\', '/')); + buf.append('"'); + } else { + buf.append(outputFile.replace('\\', '/')); + } + String[] retval = new String[]{letter, buf.toString()}; + return retval; + } + /** + * Returns the contents of the gcc specs file. + * + * The implementation locates gcc.exe in the executable path and then + * builds a relative path name from the results of -dumpmachine and + * -dumpversion. Attempts to use gcc -dumpspecs to provide this information + * resulted in stalling on the Execute.run + * + * @return contents of the specs file + */ + public static String[] getSpecs() { + if (specs == null) { + File gccParent = CUtil.getExecutableLocation("gcc.exe"); + if (gccParent != null) { + // + // build a relative path like + // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs + // + StringBuffer buf = new StringBuffer("../lib/gcc-lib/"); + buf.append(getMachine()); + buf.append('/'); + buf.append(getVersion()); + buf.append("/specs"); + // + // resolve it relative to the location of gcc.exe + // + String relativePath = buf.toString(); + File specsFile = new File(gccParent, relativePath); + // + // found the specs file + // + try { + // + // read the lines in the file + // + BufferedReader reader = new BufferedReader(new FileReader( + specsFile)); + Vector lines = new Vector(100); + String line = reader.readLine(); + while (line != null) { + lines.addElement(line); + line = reader.readLine(); + } + specs = new String[lines.size()]; + lines.copyInto(specs); + } catch (IOException ex) { + } + } + } + if (specs == null) { + specs = new String[0]; + } + return specs; + } + public static String getVersion() { + if (version == null) { + String[] args = new String[]{"gcc", "-dumpversion"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + version = "noversion"; + } else { + version = cmdout[0]; + } + } + return version; + } + public static boolean isCaseSensitive() { + return true; + } + /** + * Determines if task is running with cygwin + * + * @return true if cygwin was detected + */ + public static boolean isCygwin() { + return getMachine().indexOf("cygwin") > 0; + } + private static boolean isHPUX() { + String osname = System.getProperty("os.name").toLowerCase(); + if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) { + return true; + } + return false; + } + /** + * + * Parses the results of the specs file for a specific processor and + * options + * + * @param specsContent + * Contents of specs file as returned from getSpecs + * @param specSectionStart + * start of spec section, for example "*cpp:" + * @param options + * command line switches such as "-istart" + */ + public static String[][] parseSpecs(String[] specsContent, + String specSectionStart, String[] options) { + if (specsContent == null) { + throw new NullPointerException("specsContent"); + } + if (specSectionStart == null) { + throw new NullPointerException("specSectionStart"); + } + if (options == null) { + throw new NullPointerException("option"); + } + String[][] optionValues = new String[options.length][]; + StringBuffer optionValue = new StringBuffer(40); + for (int i = 0; i < specsContent.length; i++) { + String specLine = specsContent[i]; + // + // if start of section then start paying attention + // + if (specLine.startsWith(specSectionStart)) { + Vector[] optionVectors = new Vector[options.length]; + for (int j = 0; j < options.length; j++) { + optionVectors[j] = new Vector(10); + } + // + // go to next line and examine contents + // and repeat until end of file + // + for (i++; i < specsContent.length; i++) { + specLine = specsContent[i]; + for (int j = 0; j < options.length; j++) { + int optionStart = specLine.indexOf(options[j]); + while (optionStart >= 0) { + optionValue.setLength(0); + // + // walk rest of line looking for first non + // whitespace + // and then next space + boolean hasNonBlank = false; + int k = optionStart + options[j].length(); + for (; k < specLine.length(); k++) { + // + // either a blank or a "}" (close of + // conditional) + // section will end the path + // + if (specLine.charAt(k) == ' ' + || specLine.charAt(k) == '}') { + if (hasNonBlank) { + break; + } + } else { + hasNonBlank = true; + optionValue.append(specLine.charAt(k)); + } + } + // + // transition back to whitespace + // value is over, add it to vector + if (hasNonBlank) { + optionVectors[j].addElement(optionValue + .toString()); + } + // + // find next occurance on line + // + optionStart = specLine.indexOf(options[j], k); + } + } + } + // + // copy vectors over to option arrays + // + for (int j = 0; j < options.length; j++) { + optionValues[j] = new String[optionVectors[j].size()]; + optionVectors[j].copyInto(optionValues[j]); + } + } + } + // + // fill in any missing option values with + // a zero-length string array + for (int i = 0; i < optionValues.length; i++) { + String[] zeroLenArray = new String[0]; + if (optionValues[i] == null) { + optionValues[i] = zeroLenArray; + } + } + return optionValues; + } + private GccProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java new file mode 100644 index 0000000..b332c64 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java @@ -0,0 +1,228 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.LinkerParam; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +import net.sf.antcontrib.cpptasks.types.LibrarySet; + +import org.apache.tools.ant.BuildException; +/** + * Adapter for the g++ variant of the GCC linker + * + * @author Stephen M. Webb + */ +public class GppLinker extends AbstractLdLinker { + protected static final String[] discardFiles = new String[0]; + protected static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final GppLinker dllLinker = new GppLinker("gcc", objFiles, + discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles, + discardFiles, "lib", ".so", true, null)); + private final static String libPrefix = "libraries: ="; + protected static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static String[] linkerOptions = new String[]{"-bundle", "-dylib", + "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib", + "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"}; + private static final GppLinker instance = new GppLinker("gcc", objFiles, + discardFiles, "", "", false, null); + private static final GppLinker machDllLinker = new GppLinker("gcc", + objFiles, discardFiles, "lib", ".dylib", false, null); + private static final GppLinker machPluginLinker = new GppLinker("gcc", + objFiles, discardFiles, "lib", ".bundle", false, null); + public static GppLinker getInstance() { + return instance; + } + private File[] libDirs; + private String runtimeLibrary; + protected GppLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) { + super(command, "-dumpversion", extensions, ignoredExtensions, + outputPrefix, outputSuffix, isLibtool, libtoolLinker); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + super.addImpliedArgs(debug, linkType, args); + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + if (linkType.isStaticRuntime()) { + String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"}; + String[] cmdout = CaptureStreamHandler.run(cmdin); + if (cmdout.length > 0) { + runtimeLibrary = cmdout[0]; + } else { + runtimeLibrary = null; + } + } else { + runtimeLibrary = "-lstdc++"; + } + } + public String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + String[] rs = super.addLibrarySets(task, libsets, preargs, midargs, + endargs); + if (runtimeLibrary != null) { + endargs.addElement(runtimeLibrary); + } + return rs; + } + protected Object clone() throws CloneNotSupportedException { + GppLinker clone = (GppLinker) super.clone(); + return clone; + } + /** + * Allows drived linker to decorate linker option. Override by GppLinker to + * prepend a "-Wl," to pass option to through gcc to linker. + * + * @param buf + * buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg + * linker argument + */ + public String decorateLinkerOption(StringBuffer buf, String arg) { + String decoratedArg = arg; + if (arg.length() > 1 && arg.charAt(0) == '-') { + switch (arg.charAt(1)) { + // + // passed automatically by GCC + // + case 'g' : + case 'f' : + case 'F' : + /* Darwin */ + case 'm' : + case 'O' : + case 'W' : + case 'l' : + case 'L' : + case 'u' : + break; + default : + boolean known = false; + for (int i = 0; i < linkerOptions.length; i++) { + if (linkerOptions[i].equals(arg)) { + known = true; + break; + } + } + if (!known) { + buf.setLength(0); + buf.append("-Wl,"); + buf.append(arg); + decoratedArg = buf.toString(); + } + break; + } + } + return decoratedArg; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + Vector dirs = new Vector(); + // Ask GCC where it will look for its libraries. + String[] args = new String[]{"g++", "-print-search-dirs"}; + String[] cmdout = CaptureStreamHandler.run(args); + for (int i = 0; i < cmdout.length; ++i) { + int prefixIndex = cmdout[i].indexOf(libPrefix); + if (prefixIndex >= 0) { + // Special case DOS-type GCCs like MinGW or Cygwin + int s = prefixIndex + libPrefix.length(); + int t = cmdout[i].indexOf(';', s); + while (t > 0) { + dirs.addElement(cmdout[i].substring(s, t)); + s = t + 1; + t = cmdout[i].indexOf(';', s); + } + dirs.addElement(cmdout[i].substring(s)); + ++i; + for (; i < cmdout.length; ++i) { + dirs.addElement(cmdout[i]); + } + } + } + // Eliminate all but actual directories. + String[] libpath = new String[dirs.size()]; + dirs.copyInto(libpath); + int count = CUtil.checkDirectoryArray(libpath); + // Build return array. + libDirs = new File[count]; + int index = 0; + for (int i = 0; i < libpath.length; ++i) { + if (libpath[i] != null) { + libDirs[index++] = new File(libpath[i]); + } + } + } + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isPluginModule()) { + if (GccProcessor.getMachine().indexOf("darwin") >= 0) { + return machPluginLinker; + } else { + return dllLinker; + } + } + if (type.isSharedLibrary()) { + if (GccProcessor.getMachine().indexOf("darwin") >= 0) { + return machDllLinker; + } else { + return dllLinker; + } + } + return instance; + } + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + try { + GppLinker clone = (GppLinker) this.clone(); + LinkerParam param = config.getParam("target"); + if (param != null) + clone.setCommand(param.getValue() + "-" + this.getCommand()); + clone.superlink(task, outputFile, sourceFiles, config); + } catch (CloneNotSupportedException e) { + superlink(task, outputFile, sourceFiles, config); + } + } + private void superlink(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + super.link(task, outputFile, sourceFiles, config); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java new file mode 100644 index 0000000..26abf8c --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java @@ -0,0 +1,83 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.LinkerParam; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; + +import org.apache.tools.ant.BuildException; +/** + * Adapter for the 'ld' linker + * + * @author Curt Arnold + */ +public final class LdLinker extends AbstractLdLinker { + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final String[] discardFiles = new String[0]; + private static final LdLinker dllLinker = new LdLinker("ld", objFiles, + discardFiles, "lib", ".so", false, new LdLinker("ld", objFiles, + discardFiles, "lib", ".so", true, null)); + private static final LdLinker instance = new LdLinker("ld", objFiles, + discardFiles, "", "", false, null); + public static LdLinker getInstance() { + return instance; + } + private File[] libDirs; + private LdLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) { + super(command, "-version", extensions, ignoredExtensions, outputPrefix, + outputSuffix, isLibtool, libtoolLinker); + } + protected Object clone() throws CloneNotSupportedException { + LdLinker clone = (LdLinker) super.clone(); + return clone; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + try { + LdLinker clone = (LdLinker) this.clone(); + LinkerParam param = config.getParam("target"); + if (param != null) + clone.setCommand(param.getValue() + "-" + this.getCommand()); + clone.superlink(task, outputFile, sourceFiles, config); + } catch (CloneNotSupportedException e) { + superlink(task, outputFile, sourceFiles, config); + } + } + private void superlink(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + super.link(task, outputFile, sourceFiles, config); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java new file mode 100644 index 0000000..44dd968 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java @@ -0,0 +1,244 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.FortranParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +/** + * Adapter for the GCC C/C++ compiler + * + * @author Adam Murdoch + */ +public final class GccCCompiler extends GccCompatibleCCompiler { + private final static String[] sourceExtensions = new String[]{".c", /* C */ + ".cc", /* C++ */ + ".cpp", /* C++ */ + ".cxx", /* C++ */ + ".c++", /* C++ */ + ".i", /* preprocessed C */ + ".ii", /* preprocessed C++ */ + ".f", /* FORTRAN */ + ".for", /* FORTRAN */ + ".m", /* Objective-C */ + ".mm", /* Objected-C++ */ + ".s" /* Assembly */ + }; + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + public static final String CMD_PREFIX = "sparc-sun-solaris2-"; + private static final GccCCompiler cppInstance = new GccCCompiler(CMD_PREFIX + + "c++", sourceExtensions, headerExtensions, false, + new GccCCompiler(CMD_PREFIX + "c++", sourceExtensions, + headerExtensions, true, null, false, null), false, null); + private static final GccCCompiler g77Instance = new GccCCompiler(CMD_PREFIX + + "g77", sourceExtensions, headerExtensions, false, + new GccCCompiler(CMD_PREFIX + "g77", sourceExtensions, + headerExtensions, true, null, false, null), false, null); + private static final GccCCompiler gppInstance = new GccCCompiler(CMD_PREFIX + + "g++", sourceExtensions, headerExtensions, false, + new GccCCompiler(CMD_PREFIX + "g++", sourceExtensions, + headerExtensions, true, null, false, null), false, null); + private static final GccCCompiler instance = new GccCCompiler(CMD_PREFIX + + "gcc", sourceExtensions, headerExtensions, false, + new GccCCompiler(CMD_PREFIX + "gcc", sourceExtensions, + headerExtensions, true, null, false, null), false, null); + /** + * Gets c++ adapter + */ + public static GccCCompiler getCppInstance() { + return cppInstance; + } + /** + * Gets g77 adapter + */ + public static GccCCompiler getG77Instance() { + return g77Instance; + } + /** + * Gets gpp adapter + */ + public static GccCCompiler getGppInstance() { + return gppInstance; + } + /** + * Gets gcc adapter + */ + public static GccCCompiler getInstance() { + return instance; + } + private String identifier; + private File[] includePath; + private boolean isPICMeaningful = true; + /** + * Private constructor. Use GccCCompiler.getInstance() to get singleton + * instance of this class. + */ + private GccCCompiler(String command, String[] sourceExtensions, + String[] headerExtensions, boolean isLibtool, + GccCCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super(command, null, sourceExtensions, headerExtensions, isLibtool, + libtoolCompiler, newEnvironment, env); + isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0; + } + public void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + super.addImpliedArgs(args, debug, multithreaded, + exceptions, linkType, rtti, optimization); + if (isPICMeaningful && linkType.isSharedLibrary()) { + args.addElement("-fPIC"); + } + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new GccCCompiler(getCommand(), this.getSourceExtensions(), + this.getHeaderExtensions(), this.getLibtool(), + (GccCCompiler) this.getLibtoolCompiler(), newEnvironment, + env); + } + return this; + } + /** + * Create parser to determine dependencies. + * + * Will create appropriate parser (C++, FORTRAN) based on file extension. + * + */ + protected Parser createParser(File source) { + if (source != null) { + String sourceName = source.getName(); + int lastDot = sourceName.lastIndexOf('.'); + if (lastDot >= 0 && lastDot + 1 < sourceName.length()) { + char afterDot = sourceName.charAt(lastDot + 1); + if (afterDot == 'f' || afterDot == 'F') { + return new FortranParser(); + } + } + } + return new CParser(); + } + public File[] getEnvironmentIncludePath() { + if (includePath == null) { + // + // construct default include path from machine id and version id + // + String[] defaultInclude = new String[1]; + StringBuffer buf = new StringBuffer("/lib/"); + buf.append(GccProcessor.getMachine()); + buf.append('/'); + buf.append(GccProcessor.getVersion()); + buf.append("/include"); + defaultInclude[0] = buf.toString(); + // + // read specs file and look for -istart and -idirafter + // + String[] specs = GccProcessor.getSpecs(); + String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:", + new String[]{"-isystem ", "-idirafter "}); + // + // if no entries were found, then use a default path + // + if (optionValues[0].length == 0 && optionValues[1].length == 0) { + optionValues[0] = new String[]{"/usr/local/include", + "/usr/include", "/usr/include/win32api"}; + } + // + // remove mingw entries. + // For MinGW compiles this will mean the + // location of the sys includes will be + // wrong in dependencies.xml + // but that should have no significant effect + for (int i = 0; i < optionValues.length; i++) { + for (int j = 0; j < optionValues[i].length; j++) { + if (optionValues[i][j].indexOf("mingw") > 0) { + optionValues[i][j] = null; + } + } + } + // + // if cygwin then + // we have to prepend location of gcc32 + // and .. to start of absolute filenames to + // have something that will exist in the + // windows filesystem + if (GccProcessor.isCygwin()) { + GccProcessor.convertCygwinFilenames(optionValues[0]); + GccProcessor.convertCygwinFilenames(optionValues[1]); + GccProcessor.convertCygwinFilenames(defaultInclude); + } + int count = CUtil.checkDirectoryArray(optionValues[0]); + count += CUtil.checkDirectoryArray(optionValues[1]); + count += CUtil.checkDirectoryArray(defaultInclude); + includePath = new File[count]; + int index = 0; + for (int i = 0; i < optionValues.length; i++) { + for (int j = 0; j < optionValues[i].length; j++) { + if (optionValues[i][j] != null) { + includePath[index++] = new File(optionValues[i][j]); + } + } + } + for (int i = 0; i < defaultInclude.length; i++) { + if (defaultInclude[i] != null) { + includePath[index++] = new File(defaultInclude[i]); + } + } + } + return (File[]) includePath.clone(); + } + public String getIdentifier() throws BuildException { + if (identifier == null) { + StringBuffer buf; + if (getLibtool()) { + buf = new StringBuffer("libtool "); + } else { + buf = new StringBuffer(' '); + } + buf.append(getCommand()); + buf.append(' '); + buf.append(GccProcessor.getVersion()); + buf.append(' '); + buf.append(GccProcessor.getMachine()); + identifier = buf.toString(); + } + return identifier; + } + public Linker getLinker(LinkType linkType) { + return GccLinker.getInstance().getLinker(linkType); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java new file mode 100644 index 0000000..779fb3d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java @@ -0,0 +1,43 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractArLibrarian; +/** + * Adapter for the 'ar' archiver + * + * @author Adam Murdoch + */ +public final class GccLibrarian extends AbstractArLibrarian { + private static String[] objFileExtensions = new String[]{".o"}; + private static GccLibrarian instance = new GccLibrarian( + GccCCompiler.CMD_PREFIX + "ar", objFileExtensions, false, + new GccLibrarian(GccCCompiler.CMD_PREFIX + "ar", objFileExtensions, + true, null)); + public static GccLibrarian getInstance() { + return instance; + } + private GccLibrarian(String command, String[] inputExtensions, + boolean isLibtool, GccLibrarian libtoolLibrarian) { + super(command, "V", inputExtensions, new String[0], "lib", ".a", + isLibtool, libtoolLibrarian); + } + public Linker getLinker(LinkType type) { + return GccLinker.getInstance().getLinker(type); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java new file mode 100644 index 0000000..d7dd3db --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java @@ -0,0 +1,215 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +/** + * Adapter for the GCC linker + * + * @author Adam Murdoch + */ +public class GccLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static String[] linkerOptions = new String[]{"-bundle", + "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s", + "-static", "-shared", "-symbolic", "-Xlinker", + "--export-all-symbols", "-static-libgcc",}; + private static final GccLinker dllLinker = new GccLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", + ".so", false, new GccLinker(GccCCompiler.CMD_PREFIX + "gcc", + objFiles, discardFiles, "lib", ".so", true, null)); + private static final GccLinker instance = new GccLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "", + false, null); + private static final GccLinker machBundleLinker = new GccLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", + ".bundle", false, null); + private static final GccLinker machDllLinker = new GccLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", + ".dylib", false, null); + public static GccLinker getInstance() { + return instance; + } + private File[] libDirs; + protected GccLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) { + super(command, "-dumpversion", extensions, ignoredExtensions, + outputPrefix, outputSuffix, isLibtool, libtoolLinker); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + super.addImpliedArgs(debug, linkType, args); + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + } + /** + * Allows drived linker to decorate linker option. Override by GccLinker to + * prepend a "-Wl," to pass option to through gcc to linker. + * + * @param buf + * buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg + * linker argument + */ + public String decorateLinkerOption(StringBuffer buf, String arg) { + String decoratedArg = arg; + if (arg.length() > 1 && arg.charAt(0) == '-') { + switch (arg.charAt(1)) { + // + // passed automatically by GCC + // + case 'g' : + case 'f' : + case 'F' : + /* Darwin */ + case 'm' : + case 'O' : + case 'W' : + case 'l' : + case 'L' : + case 'u' : + case 'v' : + break; + default : + boolean known = false; + for (int i = 0; i < linkerOptions.length; i++) { + if (linkerOptions[i].equals(arg)) { + known = true; + break; + } + } + if (!known) { + buf.setLength(0); + buf.append("-Wl,"); + buf.append(arg); + decoratedArg = buf.toString(); + } + break; + } + } + return decoratedArg; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + // + // construct gcc lib path from machine and version + // + StringBuffer buf = new StringBuffer("/lib/gcc-lib/"); + buf.append(GccProcessor.getMachine()); + buf.append('/'); + buf.append(GccProcessor.getVersion()); + // + // build default path from gcc and system /lib and /lib/w32api + // + String[] impliedLibPath = new String[]{buf.toString(), + "/lib/w32api", "/lib"}; + // + // read gcc specs file for other library paths + // + String[] specs = GccProcessor.getSpecs(); + String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:", + new String[]{"%q"}); + String[] libpath; + if (libpaths[0].length > 0) { + libpath = new String[libpaths[0].length + 3]; + int i = 0; + for (; i < libpaths[0].length; i++) { + libpath[i] = libpaths[0][i]; + } + libpath[i++] = buf.toString(); + libpath[i++] = "/lib/w32api"; + libpath[i++] = "/lib"; + } else { + // + // if a failure to find any matches then + // use some default values for lib path entries + libpath = new String[]{"/usr/local/lib/mingw", + "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw", + "/usr/lib", buf.toString(), "/lib/w32api", "/lib"}; + } + for (int i = 0; i < libpath.length; i++) { + if (libpath[i].indexOf("mingw") >= 0) { + libpath[i] = null; + } + } + // + // if cygwin then + // we have to prepend location of gcc32 + // and .. to start of absolute filenames to + // have something that will exist in the + // windows filesystem + if (GccProcessor.isCygwin()) { + GccProcessor.convertCygwinFilenames(libpath); + } + // + // check that remaining entries are actual directories + // + int count = CUtil.checkDirectoryArray(libpath); + // + // populate return array with remaining entries + // + libDirs = new File[count]; + int index = 0; + for (int i = 0; i < libpath.length; i++) { + if (libpath[i] != null) { + libDirs[index++] = new File(libpath[i]); + } + } + } + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isPluginModule()) { + if (isDarwin()) { + return machBundleLinker; + } else { + return dllLinker; + } + } + if (type.isSharedLibrary()) { + if (isDarwin()) { + return machDllLinker; + } else { + return dllLinker; + } + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java new file mode 100644 index 0000000..bbcd13d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java @@ -0,0 +1,305 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * A add-in class for Gcc processors + * + * + */ +public class GccProcessor { + // the results from gcc -dumpmachine + private static String machine; + private static String[] specs; + // the results from gcc -dumpversion + private static String version; + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + /** + * Converts absolute Cygwin file or directory names to the corresponding + * Win32 name. + * + * @param names + * array of names, some elements may be null, will be changed in + * place. + */ + public static void convertCygwinFilenames(String[] names) { + if (names == null) { + throw new NullPointerException("names"); + } + File gccDir = CUtil.getExecutableLocation(GccCCompiler.CMD_PREFIX + + "gcc.exe"); + if (gccDir != null) { + String prefix = gccDir.getAbsolutePath() + "/.."; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + if (name != null && name.length() > 1 && name.charAt(0) == '/') { + buf.setLength(0); + buf.append(prefix); + buf.append(name); + names[i] = buf.toString(); + } + } + } + } + public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length * 2]; + int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + if (isHPUX()) { + offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns, + offset); + } else { + offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns, + offset); + } + return patterns; + } + public static String getMachine() { + if (machine == null) { + String[] args = new String[]{GccCCompiler.CMD_PREFIX + "gcc", + "-dumpmachine"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + machine = "nomachine"; + } else { + machine = cmdout[0]; + } + } + return machine; + } + public static String[] getOutputFileSwitch(String letter, String outputFile) { + StringBuffer buf = new StringBuffer(); + if (outputFile.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(outputFile.replace('\\', '/')); + buf.append('"'); + } else { + buf.append(outputFile.replace('\\', '/')); + } + String[] retval = new String[]{letter, buf.toString()}; + return retval; + } + /** + * Returns the contents of the gcc specs file. + * + * The implementation locates gcc.exe in the executable path and then + * builds a relative path name from the results of -dumpmachine and + * -dumpversion. Attempts to use gcc -dumpspecs to provide this information + * resulted in stalling on the Execute.run + * + * @return contents of the specs file + */ + public static String[] getSpecs() { + if (specs == null) { + File gccParent = CUtil + .getExecutableLocation(GccCCompiler.CMD_PREFIX + "gcc.exe"); + if (gccParent != null) { + // + // build a relative path like + // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs + // + StringBuffer buf = new StringBuffer("../lib/gcc-lib/"); + buf.append(getMachine()); + buf.append('/'); + buf.append(getVersion()); + buf.append("/specs"); + // + // resolve it relative to the location of gcc.exe + // + String relativePath = buf.toString(); + File specsFile = new File(gccParent, relativePath); + // + // found the specs file + // + try { + // + // read the lines in the file + // + BufferedReader reader = new BufferedReader(new FileReader( + specsFile)); + Vector lines = new Vector(100); + String line = reader.readLine(); + while (line != null) { + lines.addElement(line); + line = reader.readLine(); + } + specs = new String[lines.size()]; + lines.copyInto(specs); + } catch (IOException ex) { + } + } + } + if (specs == null) { + specs = new String[0]; + } + return specs; + } + public static String getVersion() { + if (version == null) { + String[] args = new String[]{GccCCompiler.CMD_PREFIX + "gcc", + "-dumpversion"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + version = "noversion"; + } else { + version = cmdout[0]; + } + } + return version; + } + public static boolean isCaseSensitive() { + return true; + } + /** + * Determines if task is running with cygwin + * + * @return true if cygwin was detected + */ + public static boolean isCygwin() { + return getMachine().indexOf("cygwin") > 0; + } + private static boolean isHPUX() { + String osname = System.getProperty("os.name").toLowerCase(); + if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) { + return true; + } + return false; + } + /** + * + * Parses the results of the specs file for a specific processor and + * options + * + * @param specsContent + * Contents of specs file as returned from getSpecs + * @param specSectionStart + * start of spec section, for example "*cpp:" + * @param options + * command line switches such as "-istart" + */ + public static String[][] parseSpecs(String[] specsContent, + String specSectionStart, String[] options) { + if (specsContent == null) { + throw new NullPointerException("specsContent"); + } + if (specSectionStart == null) { + throw new NullPointerException("specSectionStart"); + } + if (options == null) { + throw new NullPointerException("option"); + } + String[][] optionValues = new String[options.length][]; + StringBuffer optionValue = new StringBuffer(40); + for (int i = 0; i < specsContent.length; i++) { + String specLine = specsContent[i]; + // + // if start of section then start paying attention + // + if (specLine.startsWith(specSectionStart)) { + Vector[] optionVectors = new Vector[options.length]; + for (int j = 0; j < options.length; j++) { + optionVectors[j] = new Vector(10); + } + // + // go to next line and examine contents + // and repeat until end of file + // + for (i++; i < specsContent.length; i++) { + specLine = specsContent[i]; + for (int j = 0; j < options.length; j++) { + int optionStart = specLine.indexOf(options[j]); + while (optionStart >= 0) { + optionValue.setLength(0); + // + // walk rest of line looking for first non + // whitespace + // and then next space + boolean hasNonBlank = false; + int k = optionStart + options[j].length(); + for (; k < specLine.length(); k++) { + // + // either a blank or a "}" (close of + // conditional) + // section will end the path + // + if (specLine.charAt(k) == ' ' + || specLine.charAt(k) == '}') { + if (hasNonBlank) { + break; + } + } else { + hasNonBlank = true; + optionValue.append(specLine.charAt(k)); + } + } + // + // transition back to whitespace + // value is over, add it to vector + if (hasNonBlank) { + optionVectors[j].addElement(optionValue + .toString()); + } + // + // find next occurance on line + // + optionStart = specLine.indexOf(options[j], k); + } + } + } + // + // copy vectors over to option arrays + // + for (int j = 0; j < options.length; j++) { + optionValues[j] = new String[optionVectors[j].size()]; + optionVectors[j].copyInto(optionValues[j]); + } + } + } + // + // fill in any missing option values with + // a zero-length string array + for (int i = 0; i < optionValues.length; i++) { + String[] zeroLenArray = new String[0]; + if (optionValues[i] == null) { + optionValues[i] = zeroLenArray; + } + } + return optionValues; + } + private GccProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java new file mode 100644 index 0000000..45bbea9 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java @@ -0,0 +1,210 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +/** + * Adapter for the g++ variant of the GCC linker + * + * @author Stephen M. Webb + */ +public class GppLinker extends AbstractLdLinker { + protected static final String[] discardFiles = new String[0]; + protected static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private final static String libPrefix = "libraries: ="; + protected static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static String[] linkerOptions = new String[]{"-bundle", "-dylib", + "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib", + "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"}; + private static final GppLinker dllLinker = new GppLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", + ".so", false, new GppLinker(GccCCompiler.CMD_PREFIX + "gcc", + objFiles, discardFiles, "lib", ".so", true, null)); + private static final GppLinker instance = new GppLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "", + false, null); + private static final GppLinker machDllLinker = new GppLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", + ".dylib", false, null); + private static final GppLinker machPluginLinker = new GppLinker( + GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", + ".bundle", false, null); + public static GppLinker getInstance() { + return instance; + } + private File[] libDirs; + private String runtimeLibrary; + protected GppLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) { + super(command, "-dumpversion", extensions, ignoredExtensions, + outputPrefix, outputSuffix, isLibtool, libtoolLinker); + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + super.addImpliedArgs(debug, linkType, args); + if (getIdentifier().indexOf("mingw") >= 0) { + if (linkType.isSubsystemConsole()) { + args.addElement("-mconsole"); + } + if (linkType.isSubsystemGUI()) { + args.addElement("-mwindows"); + } + } + if (linkType.isStaticRuntime()) { + String[] cmdin = new String[]{GccCCompiler.CMD_PREFIX + "g++", + "-print-file-name=libstdc++.a"}; + String[] cmdout = CaptureStreamHandler.run(cmdin); + if (cmdout.length > 0) { + runtimeLibrary = cmdout[0]; + } else { + runtimeLibrary = null; + } + } else { + runtimeLibrary = "-lstdc++"; + } + } + public String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + String[] rs = super.addLibrarySets(task, libsets, preargs, midargs, + endargs); + if (runtimeLibrary != null) { + endargs.addElement(runtimeLibrary); + } + return rs; + } + /** + * Allows drived linker to decorate linker option. Override by GppLinker to + * prepend a "-Wl," to pass option to through gcc to linker. + * + * @param buf + * buffer that may be used and abused in the decoration process, + * must not be null. + * @param arg + * linker argument + */ + public String decorateLinkerOption(StringBuffer buf, String arg) { + String decoratedArg = arg; + if (arg.length() > 1 && arg.charAt(0) == '-') { + switch (arg.charAt(1)) { + // + // passed automatically by GCC + // + case 'g' : + case 'f' : + case 'F' : + /* Darwin */ + case 'm' : + case 'O' : + case 'W' : + case 'l' : + case 'L' : + case 'u' : + break; + default : + boolean known = false; + for (int i = 0; i < linkerOptions.length; i++) { + if (linkerOptions[i].equals(arg)) { + known = true; + break; + } + } + if (!known) { + buf.setLength(0); + buf.append("-Wl,"); + buf.append(arg); + decoratedArg = buf.toString(); + } + break; + } + } + return decoratedArg; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + Vector dirs = new Vector(); + // Ask GCC where it will look for its libraries. + String[] args = new String[]{GccCCompiler.CMD_PREFIX + "g++", + "-print-search-dirs"}; + String[] cmdout = CaptureStreamHandler.run(args); + for (int i = 0; i < cmdout.length; ++i) { + int prefixIndex = cmdout[i].indexOf(libPrefix); + if (prefixIndex >= 0) { + // Special case DOS-type GCCs like MinGW or Cygwin + int s = prefixIndex + libPrefix.length(); + int t = cmdout[i].indexOf(';', s); + while (t > 0) { + dirs.addElement(cmdout[i].substring(s, t)); + s = t + 1; + t = cmdout[i].indexOf(';', s); + } + dirs.addElement(cmdout[i].substring(s)); + ++i; + for (; i < cmdout.length; ++i) { + dirs.addElement(cmdout[i]); + } + } + } + // Eliminate all but actual directories. + String[] libpath = new String[dirs.size()]; + dirs.copyInto(libpath); + int count = CUtil.checkDirectoryArray(libpath); + // Build return array. + libDirs = new File[count]; + int index = 0; + for (int i = 0; i < libpath.length; ++i) { + if (libpath[i] != null) { + libDirs[index++] = new File(libpath[i]); + } + } + } + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isPluginModule()) { + if (GccProcessor.getMachine().indexOf("darwin") >= 0) { + return machPluginLinker; + } else { + return dllLinker; + } + } + if (type.isSharedLibrary()) { + if (GccProcessor.getMachine().indexOf("darwin") >= 0) { + return machDllLinker; + } else { + return dllLinker; + } + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java new file mode 100644 index 0000000..0cc5fbf --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java @@ -0,0 +1,60 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2; +import java.io.File; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +/** + * Adapter for the 'ld' linker + * + * @author Curt Arnold + */ +public final class LdLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final LdLinker dllLinker = new LdLinker( + GccCCompiler.CMD_PREFIX + "ld", objFiles, discardFiles, "lib", + ".so", false, new LdLinker(GccCCompiler.CMD_PREFIX + "ld", + objFiles, discardFiles, "lib", ".so", true, null)); + private static final LdLinker instance = new LdLinker( + GccCCompiler.CMD_PREFIX + "ld", objFiles, discardFiles, "", "", + false, null); + public static LdLinker getInstance() { + return instance; + } + private File[] libDirs; + private LdLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, + String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) { + super(command, "-version", extensions, ignoredExtensions, outputPrefix, + outputSuffix, isLibtool, libtoolLinker); + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java new file mode 100644 index 0000000..b978f67 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java @@ -0,0 +1,116 @@ +/* + * + * Copyright 2001-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.hp; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the HP aC++ C++ compiler + * + * @author Curt Arnold + */ +public final class aCCCompiler extends GccCompatibleCCompiler { + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private final static String[] sourceExtensions = new String[]{".c", ".cc", + ".cxx", ".cpp", ".c++", ".i", ".s"}; + + private static final aCCCompiler instance = new aCCCompiler("aCC", + sourceExtensions, headerExtensions, false, null); + /** + * Gets singleton instance of this class + */ + public static aCCCompiler getInstance() { + return instance; + } + private String identifier; + private File[] includePath; + /** + * Private constructor. Use GccCCompiler.getInstance() to get singleton + * instance of this class. + */ + private aCCCompiler(String command, String[] sourceExtensions, + String[] headerExtensions, boolean newEnvironment, + Environment env) { + super(command, "-help", sourceExtensions, headerExtensions, false, + null, newEnvironment, env); + } + public void addImpliedArgs(Vector args, boolean debug, + boolean multithreaded, boolean exceptions, LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("-c"); + if (debug) { + args.addElement("-g"); + } + /* + * if (multithreaded) { args.addElement("-mt"); } + */ + + // + // per patch 1193690 + // + if (linkType.isSharedLibrary() && (! args.contains("+Z"))) { + args.addElement("+z"); + } + } + public void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("-w"); + break; + case 1 : + case 2 : + args.addElement("+w"); + break; + /* + * case 3: case 4: case 5: args.addElement("+w2"); break; + */ + } + } + public File[] getEnvironmentIncludePath() { + if (includePath == null) { + File ccLoc = CUtil.getExecutableLocation("aCC"); + if (ccLoc != null) { + File compilerIncludeDir = new File( + new File(ccLoc, "../include").getAbsolutePath()); + if (compilerIncludeDir.exists()) { + includePath = new File[2]; + includePath[0] = compilerIncludeDir; + } + } + if (includePath == null) { + includePath = new File[1]; + } + includePath[includePath.length - 1] = new File("/usr/include"); + } + return includePath; + } + public Linker getLinker(LinkType linkType) { + return aCCLinker.getInstance().getLinker(linkType); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java new file mode 100644 index 0000000..94f7fc0 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/hp/aCCLinker.java @@ -0,0 +1,100 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.hp; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +/** + * Adapter for Sun (r) Forte(tm) C++ Linker + * + * @author Curt Arnold + */ +public final class aCCLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final aCCLinker arLinker = new aCCLinker("aCC", objFiles, + discardFiles, "", ".a"); + private static final aCCLinker dllLinker = new aCCLinker("aCC", objFiles, + discardFiles, "lib", ".sl"); + private static final aCCLinker instance = new aCCLinker("aCC", objFiles, + discardFiles, "", ""); + public static aCCLinker getInstance() { + return instance; + } + private File[] libDirs; + private aCCLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, String outputSuffix) { + super(command, "-help", extensions, ignoredExtensions, outputPrefix, + outputSuffix, false, null); + } + public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (debug) { + args.addElement("-g"); + } + /* + * if(linkType.isStaticRuntime()) { args.addElement("-static"); } + */ + if (linkType.isSharedLibrary()) { + args.addElement("-b"); + } + /* + * if (linkType.isStaticLibrary()) { args.addElement("-Wl,-noshared"); } + */ + } + public void addIncremental(boolean incremental, Vector args) { + /* + * if (incremental) { args.addElement("-xidlon"); } else { + * args.addElement("-xidloff"); } + */ + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + File CCloc = CUtil.getExecutableLocation("aCC"); + if (CCloc != null) { + File compilerLib = new File(new File(CCloc, "../lib") + .getAbsolutePath()); + if (compilerLib.exists()) { + libDirs = new File[2]; + libDirs[0] = compilerLib; + } + } + if (libDirs == null) { + libDirs = new File[1]; + } + } + libDirs[libDirs.length - 1] = new File("/usr/lib"); + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return arLinker; + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java new file mode 100644 index 0000000..781b6de --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java @@ -0,0 +1,118 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ibm; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the IBM(r) Visual Age(tm) C++ compiler for AIX(tm) + * + * @author Curt Arnold + */ +public final class VisualAgeCCompiler extends GccCompatibleCCompiler { + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private final static String[] sourceExtensions = new String[]{".c", ".cc", + ".cxx", ".cpp", ".i", ".s"}; + + private static final VisualAgeCCompiler instance = new VisualAgeCCompiler( + "xlC", sourceExtensions, headerExtensions, false, null); + /** + * Gets singleton instance of this class + */ + public static VisualAgeCCompiler getInstance() { + return instance; + } + private String identifier; + private File[] includePath; + /** + * Private constructor. Use getInstance() to get singleton instance of this + * class. + */ + private VisualAgeCCompiler(String command, String[] sourceExtensions, + String[] headerExtensions, boolean newEnvironment, + Environment env) { + super(command, "-help", sourceExtensions, headerExtensions, false, + null, newEnvironment, env); + } + public void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("-c"); + if (debug) { + args.addElement("-g"); + } + if (linkType.isSharedLibrary()) { + args.addElement("-fpic"); + } + if (rtti != null) { + if (rtti.booleanValue()) { + args.addElement("-qrtti=all"); + } else { + args.addElement("-qnortti"); + } + } + } + public void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("-w"); + break; + case 1 : + args.addElement("-qflag=s:s"); + break; + case 2 : + args.addElement("-qflag=e:e"); + break; + case 3 : + args.addElement("-qflag=w:w"); + break; + case 4 : + args.addElement("-qflag=i:i"); + break; + case 5 : + args.addElement("-qhalt=w:w"); + break; + } + } + public Linker getLinker(LinkType linkType) { + return VisualAgeLinker.getInstance().getLinker(linkType); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + /** + * Gets identifier for the compiler. + * + * Initial attempt at extracting version information + * would lock up. Using a stock response. + */ + public String getIdentifier() { + return "VisualAge compiler - unidentified version"; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java new file mode 100644 index 0000000..59ad6a3 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java @@ -0,0 +1,83 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ibm; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +import net.sf.antcontrib.cpptasks.gcc.GccLibrarian; +/** + * Adapter for IBM(r) Visual Age(tm) Linker for AIX(tm) + * + * @author Curt Arnold + */ +public final class VisualAgeLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[]{}; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final VisualAgeLinker dllLinker = new VisualAgeLinker( + "xlC", objFiles, discardFiles, "lib", ".a"); + private static final VisualAgeLinker instance = new VisualAgeLinker("xlC", + objFiles, discardFiles, "", ""); + public static VisualAgeLinker getInstance() { + return instance; + } + private VisualAgeLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, String outputSuffix) { + // + // just guessing that -? might display something useful + // + super(command, "-?", extensions, ignoredExtensions, outputPrefix, + outputSuffix, false, null); + } + public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (debug) { + //args.addElement("-g"); + } + if (linkType.isSharedLibrary()) { + args.addElement("-qmkshrobj"); + } + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } + /** + * Gets identifier for the compiler. + * + * Initial attempt at extracting version information + * would lock up. Using a stock response. + */ + public String getIdentifier() { + return "VisualAge linker - unidentified version"; + } + + protected String getDynamicLibFlag() { + return "-bdynamic"; + } + + protected String getStaticLibFlag() { + return "-bstatic"; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java new file mode 100644 index 0000000..2221aba --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/CommentDef.java @@ -0,0 +1,47 @@ +/* + * + * Copyright 2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ide; + +import org.apache.tools.ant.util.StringUtils; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +/** + * Defines a comment to place in the generated project files. + * + */ +public final class CommentDef { + private String text; + + public CommentDef() { + text = ""; + } + + + public String getText() { + return text; + } + public void addText(final String newText) { + text += newText; + } + + public String toString() { + return text; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java new file mode 100644 index 0000000..8ddd04e --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/DebugDef.java @@ -0,0 +1,127 @@ +/* +* +* Copyright 2004-2005 The Ant-Contrib project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package net.sf.antcontrib.cpptasks.ide; + +import java.io.File; + +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.Environment; +import org.apache.tools.ant.types.DataType; + + +/** +* Specifies a debugging configuration for a project. +* +* @author Curt Arnold +*/ +public final class DebugDef + extends DataType { + + /** + * Working directory for debug runs. + */ + private File dir; + /** + * Name of executable. + */ + private String executable; + /** + * Environment used to hold environment variables. + */ + private Environment env = new Environment(); + /** + * Command line used to hold command line arguments. + */ + private Commandline cmdl = new Commandline(); + + /** + * Constructor. + * + */ + public DebugDef() { + } + + + /** + * Set the name of the executable program. + * @param value the name of the executable program + */ + public void setExecutable(final String value) { + this.executable = value; + } + + /** + * Get the name of the executable program. + * @return the name of the executable program, may be null. + */ + public String getExecutable() { + return executable; + } + + /** + * Set the working directory of the process. + * @param d the working directory of the process + */ + public void setDir(final File d) { + this.dir = d; + } + + /** + * Get the working directory of the process. + * @return the working directory of the process, may be null. + */ + public File getDir() { + return dir; + } + + /** + * Add an environment variable. + * + * @param var new environment variable + */ + public void addEnv(final Environment.Variable var) { + env.addVariable(var); + } + + /** + * Get the variable list as an array. + * @return array of key=value assignment strings + */ + public String[] getVariables() { + return env.getVariables(); + } + + + /** + * Adds a command-line argument. + * + * @return new command line argument created + */ + public Commandline.Argument createArg() { + return cmdl.createArgument(); + } + + /** + * Returns all arguments defined by addLine, + * addValue or the argument object. + * @return array of command line arguments, may be zero-length. + */ + public String[] getArguments() { + return cmdl.getArguments(); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java new file mode 100644 index 0000000..a04cad1 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/DependencyDef.java @@ -0,0 +1,77 @@ +/* + * + * Copyright 2004-2006 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ide; + +import org.apache.tools.ant.util.StringUtils; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +/** + * Defines a dependency + * + */ +public final class DependencyDef { + private String id; + private File file; + private String name; + private String depends; + + public DependencyDef() { + } + + + public void setID(final String val) { + id = val; + } + public File getFile() { + return file; + } + public void setFile(final File val) { + file = val; + } + public void setName(final String val) { + name = val; + } + public String getName() { + if (name != null) { + return name; + } else if(file != null) { + return file.getName(); + } + return "null"; + } + public String getID() { + if (id != null) { + return id; + } + return getName(); + } + public String getDepends() { + return depends; + } + public void setDepends(final String val) { + depends = val; + } + public List getDependsList() { + if (depends != null) { + return StringUtils.split(depends, ','); + } + return Collections.EMPTY_LIST; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java new file mode 100644 index 0000000..8883ebb --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectDef.java @@ -0,0 +1,372 @@ +/* + * + * Copyright 2004-2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ide; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetInfo; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +/** + * Requests the creation of an IDE project file. Experimental. + * + * Implementation status: msdev5, msdev6 and cbuilderx + * generate reasonable project files for simple projects, + * xcode and msdev7 and msdev71 capture source file lists and + * a few settings. + * + * @author Curt Arnold + */ +public final class ProjectDef + extends DataType { + /** + * Name of property that must be present or definition will be ignored. May + * be null. + */ + private String ifProp; + + /** + * Name of property that must be absent or definition will be ignored. May + * be null. + */ + private String unlessProp; + + /** + * Project file name. + */ + private File outFile; + + /** + * Project name. + */ + private String name; + + /** + * Fail on error. + */ + private boolean failOnError = true; + + /** + * Overwrite existing project file. + */ + private boolean overwrite = true; + + /** + * Project writer. + */ + private ProjectWriter projectWriter; + + /** + * Object directory. + * + */ + private File objDir; + + /** + * List of dependency definitions. + */ + private List dependencies = new ArrayList(); + + /** + * List of comments. + */ + private List comments = new ArrayList(); + + /** + * Constructor. + * + */ + public ProjectDef() { + } + + /** + * Set project type. + * + * + * Supported project formats + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
cbuilderxBorland C++BuilderX
msvc5Microsoft Visual C++ 97
msvc6Microsoft Visual C++ 6
msvc7Microsoft Visual C++.NET
msvc71Microsoft Visual C++.NET 2003
msvc8Microsoft Visual C++ 2005
msvc9Microsoft Visual C++ 2008
xcodeApple Xcode
+ * + * @param value new value + */ + public void setType(final ProjectWriterEnum value) { + projectWriter = value.getProjectWriter(); + } + + /** + * Sets the name for the generated project file. + * + * @param outfile + * output file name + */ + public void setOutfile(final File outfile) { + // + // if file name was empty, skip link step + // + if (outfile == null || outfile.toString().length() > 0) { + outFile = outfile; + } + } + + /** + * Sets whether a failure to write the project file should cause the + * task to fail. Default is true. + * + * @param value new value + */ + public void setFailonerror(final boolean value) { + failOnError = value; + } + + /** + * Sets whether an existing project file should be overwritten, + * default is true. If false and the project file exists, + * the value of failonerror will determine if the task fails. + * + * @param value new value + */ + public void setOverwrite(final boolean value) { + overwrite = value; + } + + /** + * Gets whether an existing project file should be overwritten, + * default is true. If false and the project file exists, + * the value of failonerror will determine if the task fails. + * + * @return value + */ + public boolean getOverwrite() { + return overwrite; + } + + /** + * Determine if this def should be used. + * + * Definition will be active if the "if" variable (if specified) is set and + * the "unless" variable (if specified) is not set and that all reference + * or extended definitions are active + * + * @return true if processor is active + */ + public boolean isActive() { + Project project = getProject(); + if (!CUtil.isActive(project, ifProp, unlessProp)) { + return false; + } + return true; + } + + /** + * Class name for a user-supplied project writer. Use the "type" + * attribute to specify built-in project writer implementations. + * + * @param className + * full class name + * + */ + public void setClassname(final String className) { + Object proc = null; + try { + Class implClass = ProjectDef.class.getClassLoader().loadClass( + className); + try { + Method getInstance = implClass.getMethod("getInstance", + new Class[0]); + proc = getInstance.invoke(null, new Object[0]); + } catch (Exception ex) { + proc = implClass.newInstance(); + } + } catch (Exception ex) { + throw new BuildException(ex); + } + projectWriter = (ProjectWriter) proc; + } + + /** + * Sets the property name for the 'if' condition. + * + * The configuration will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * name of property + */ + public void setIf(final String propName) { + ifProp = propName; + } + + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the configuration will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(final String propName) { + unlessProp = propName; + } + + /** + * Get name. + * @return String name + */ + public String getName() { + return name; + } + + /** + * Set name. + * @param value String name + */ + public void setName(final String value) { + name = value; + } + + /** + * Executes the task. Compiles the given files. + * + * @param task cc task + * @param sources source files (includes headers) + * @param targets compilation targets + * @param linkTarget link target + */ + public void execute(final CCTask task, + final List sources, + final Hashtable targets, + final TargetInfo linkTarget) { + try { + projectWriter.writeProject(outFile, + task, + this, + sources, + targets, + linkTarget); + } catch (BuildException ex) { + if (failOnError) { + throw ex; + } else { + task.log(ex.toString()); + } + } catch (Exception ex) { + if (failOnError) { + throw new BuildException(ex); + } else { + task.log(ex.toString()); + } + } + } + + /** + * Gets the object files directory. + * @return directory, may be null. + */ + public File getObjdir() { + return objDir; + } + /** + * Sets the directory used for object files. If not specified, + * the object files directory from cc task will be used. + * @param oDir object file directory. + */ + public void getObjdir(final File oDir) { + this.objDir = oDir; + } + + /** + * Add a dependency definition to the project. + * @param dependency dependency. + */ + public void addDependency(final DependencyDef dependency) { + dependencies.add(dependency); + + } + + public List getDependencies() { + return new ArrayList(dependencies); + } + + + /** + * Add comment for the generated project file. + * @param comment comment, may not be null. + */ + public void addComment(final CommentDef comment) { + comments.add(comment); + + } + + public List getComments() { + return new ArrayList(comments); + } + + /** + * Required by documentation generator. + */ + public void execute() { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java new file mode 100644 index 0000000..c4c144d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriter.java @@ -0,0 +1,53 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ide; + +import java.io.File; +import java.io.IOException; +import java.util.Hashtable; +import java.util.List; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.TargetInfo; +import org.xml.sax.SAXException; + +/** + * Project writer interface. + * + * @author curta + * + */ +public interface ProjectWriter { + /** + * Write project definition file. + * @param baseName File name base, writer may append appropriate extension + * @param task task + * @param projectDef project element + * @param files source and header files + * @param targets compilation targets + * @param linkTarget link target + * @throws IOException if I/O error is encountered + * @throws SAXException if I/O error during XML serialization + */ + void writeProject(final File baseName, + final CCTask task, + final ProjectDef projectDef, + final List files, + final Hashtable targets, + final TargetInfo linkTarget) + throws IOException, SAXException; +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java new file mode 100644 index 0000000..a50a7b2 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/ProjectWriterEnum.java @@ -0,0 +1,105 @@ +/* + * + * Copyright 2004-2008 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks.ide; + +import net.sf.antcontrib.cpptasks.apple.XcodeProjectWriter; +import net.sf.antcontrib.cpptasks.borland.CBuilderXProjectWriter; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioProjectWriter; +import net.sf.antcontrib.cpptasks.devstudio.VisualStudioNETProjectWriter; +import org.apache.tools.ant.types.EnumeratedAttribute; + +/** + * Enumeration of supported project file generators. + * + * Supported project generators + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
cbuilderxBorland C++BuilderX
msvc5Microsoft Visual C++ 97
msvc6Microsoft Visual C++ 6
msvc7Microsoft Visual C++.NET
msvc71Microsoft Visual C++.NET 2003
msvc8Microsoft Visual C++ 2005
msvc9Microsoft Visual C++ 2008
xcodeApple Xcode
+ * + * @author Curt Arnold + * + */ +public final class ProjectWriterEnum + extends EnumeratedAttribute { + /** + * Enumeration values. + */ + private static String[] values = new String[] { + "cbuilderx", "msvc5", + "msvc6", "msvc7", "msvc71", "msvc8", "msvc9", "xcode"}; + + /** + * Project writers associated with enumeration values. + */ + private static ProjectWriter[] writers = new ProjectWriter[] { + new CBuilderXProjectWriter(), new DevStudioProjectWriter("5.00"), + new DevStudioProjectWriter("6.00"), + new VisualStudioNETProjectWriter("7.00", "TRUE", "FALSE"), + new VisualStudioNETProjectWriter("7.10", "TRUE", "FALSE"), + new VisualStudioNETProjectWriter("8.00", "true", "false"), + new VisualStudioNETProjectWriter("9.00", "true", "false"), + new XcodeProjectWriter()}; + + /** + * Gets ProjectWriter associated with enumeration value. + * + * @return project writer + */ + public ProjectWriter getProjectWriter() { + return writers[this.getIndex()]; + } + + /** + * Gets acceptible values for enumeration. + * + * @return acceptible values + */ + public String[] getValues() { + return (String[]) values.clone(); + } +} + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ide/package.html b/src/main/java/net/sf/antcontrib/cpptasks/ide/package.html new file mode 100644 index 0000000..ed0de56 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ide/package.html @@ -0,0 +1,27 @@ + + + + + + + +IDE project file generation. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java new file mode 100644 index 0000000..12fd5bd --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java @@ -0,0 +1,58 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Intel (r) C/C++ compiler for IA-32 Linux (r) + * + * The Intel (r) C/C++ compiler for IA32 Linux mimics the command options for + * gcc compiler. + * + * @author Curt Arnold + */ +public final class IntelLinux32CCompiler extends GccCompatibleCCompiler { + private static final IntelLinux32CCompiler instance = new IntelLinux32CCompiler( + false, new IntelLinux32CCompiler(true, null, false, null), false, + null); + public static IntelLinux32CCompiler getInstance() { + return instance; + } + private IntelLinux32CCompiler(boolean isLibtool, + IntelLinux32CCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super("icc", "-V", isLibtool, libtoolCompiler, newEnvironment, env); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new IntelLinux32CCompiler(getLibtool(), + (IntelLinux32CCompiler) getLibtoolCompiler(), + newEnvironment, env); + } + return this; + } + public Linker getLinker(LinkType type) { + return IntelLinux32Linker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java new file mode 100644 index 0000000..9bed915 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java @@ -0,0 +1,55 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +import net.sf.antcontrib.cpptasks.gcc.GccLibrarian; +/** + * Adapter for the Intel (r) Linker for Linux (r) for IA-32 + * + * @author Curt Arnold + */ +public final class IntelLinux32Linker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final IntelLinux32Linker dllLinker = new IntelLinux32Linker( + "lib", ".so", false, new IntelLinux32Linker("lib", ".so", true, + null)); + private static final IntelLinux32Linker instance = new IntelLinux32Linker( + "", "", false, null); + public static IntelLinux32Linker getInstance() { + return instance; + } + private IntelLinux32Linker(String outputPrefix, String outputSuffix, + boolean isLibtool, IntelLinux32Linker libtoolLinker) { + super("icc", "-V", objFiles, discardFiles, outputPrefix, outputSuffix, + isLibtool, libtoolLinker); + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java new file mode 100644 index 0000000..9ed6393 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java @@ -0,0 +1,58 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Intel (r) C/C++ compiler for IA-64 Linux (r) + * + * The Intel C/C++ compiler for IA-64 Linux mimics the command options for gcc + * compiler. + * + * @author Curt Arnold + */ +public final class IntelLinux64CCompiler extends GccCompatibleCCompiler { + private static final IntelLinux64CCompiler instance = new IntelLinux64CCompiler( + false, new IntelLinux64CCompiler(true, null, false, null), false, + null); + public static IntelLinux64CCompiler getInstance() { + return instance; + } + private IntelLinux64CCompiler(boolean isLibtool, + IntelLinux64CCompiler libtoolCompiler, boolean newEnvironment, + Environment env) { + super("ecc", "-V", isLibtool, libtoolCompiler, newEnvironment, env); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new IntelLinux64CCompiler(getLibtool(), + (IntelLinux64CCompiler) this.getLibtoolCompiler(), + newEnvironment, env); + } + return this; + } + public Linker getLinker(LinkType type) { + return IntelLinux64Linker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java new file mode 100644 index 0000000..d712e5b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java @@ -0,0 +1,55 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +import net.sf.antcontrib.cpptasks.gcc.GccLibrarian; +/** + * Adapter for the Intel (r) linker for Linux for IA-64 + * + * @author Curt Arnold + */ +public final class IntelLinux64Linker extends AbstractLdLinker { + private static final String[] discardFiles = new String[0]; + private static final String[] libtoolObjFiles = new String[]{".fo", ".a", + ".lib", ".dll", ".so", ".sl"}; + private static final String[] objFiles = new String[]{".o", ".a", ".lib", + ".dll", ".so", ".sl"}; + private static final IntelLinux64Linker dllLinker = new IntelLinux64Linker( + "lib", ".so", false, new IntelLinux64Linker("lib", ".so", true, + null)); + private static final IntelLinux64Linker instance = new IntelLinux64Linker( + "", "", false, null); + public static IntelLinux64Linker getInstance() { + return instance; + } + private IntelLinux64Linker(String outputPrefix, String outputSuffix, + boolean isLibtool, IntelLinux64Linker libtoolLinker) { + super("ecc", "-V", objFiles, discardFiles, outputPrefix, outputSuffix, + isLibtool, libtoolLinker); + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return GccLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java new file mode 100644 index 0000000..ed7c61a --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java @@ -0,0 +1,51 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.devstudio.DevStudioProcessor; +/** + * A add-in class for Intel (r) compilers and linkers + * + * + */ +public class IntelProcessor { + public static void addWarningSwitch(Vector args, int level) { + DevStudioProcessor.addWarningSwitch(args, level); + } + public static String getCommandFileSwitch(String cmdFile) { + return DevStudioProcessor.getCommandFileSwitch(cmdFile); + } + public static void getDefineSwitch(StringBuffer buffer, String define, + String value) { + DevStudioProcessor.getDefineSwitch(buffer, define, value); + } + public static String getIncludeDirSwitch(String includeDir) { + return DevStudioProcessor.getIncludeDirSwitch(includeDir); + } + public static String[] getOutputFileSwitch(String outPath) { + return DevStudioProcessor.getOutputFileSwitch(outPath); + } + public static void getUndefineSwitch(StringBuffer buffer, String define) { + DevStudioProcessor.getUndefineSwitch(buffer, define); + } + public static boolean isCaseSensitive() { + return false; + } + private IntelProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java new file mode 100644 index 0000000..80ade19 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java @@ -0,0 +1,52 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleCCompiler; +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Intel (r) C++ compiler for 32-bit applications + * + * The Intel (r) C++ compiler for IA32 Windows mimics the command options for + * the Microsoft (r) C++ compiler. + * + * @author Curt Arnold + */ +public final class IntelWin32CCompiler extends DevStudioCompatibleCCompiler { + private static final IntelWin32CCompiler instance = new IntelWin32CCompiler( + false, null); + public static IntelWin32CCompiler getInstance() { + return instance; + } + private IntelWin32CCompiler(boolean newEnvironment, Environment env) { + super("icl", "-help", newEnvironment, env); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new IntelWin32CCompiler(newEnvironment, env); + } + return this; + } + public Linker getLinker(LinkType type) { + return IntelWin32Linker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java new file mode 100644 index 0000000..e9473d5 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java @@ -0,0 +1,38 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLibrarian; +/** + * Adapter for the xilib from the Intel(r) C++ Compiler for IA-32 or IA-64 + * systems running Microsoft (r) operating systems + * + * @author Curt Arnold + */ +public class IntelWin32Librarian extends DevStudioCompatibleLibrarian { + private static final IntelWin32Librarian instance = new IntelWin32Librarian(); + public static IntelWin32Librarian getInstance() { + return instance; + } + protected IntelWin32Librarian() { + super("xilib", "-qv"); + } + public Linker getLinker(LinkType type) { + return IntelWin32Linker.getInstance().getLinker(type); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java new file mode 100644 index 0000000..66009f0 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java @@ -0,0 +1,46 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLinker; +/** + * Adapter for the Intel (r) linker for 32-bit applications + * + * @author Curt Arnold + */ +public final class IntelWin32Linker extends DevStudioCompatibleLinker { + private static final IntelWin32Linker dllLinker = new IntelWin32Linker( + ".dll"); + private static final IntelWin32Linker instance = new IntelWin32Linker( + ".exe"); + public static IntelWin32Linker getInstance() { + return instance; + } + private IntelWin32Linker(String outputSuffix) { + super("xilink", "-qv", outputSuffix); + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return IntelWin32Librarian.getInstance(); + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java new file mode 100644 index 0000000..6344022 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java @@ -0,0 +1,53 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.intel; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleCCompiler; + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Intel C++ compiler for Itanium(TM) Applications + * + * @author Curt Arnold + */ +public final class IntelWin64CCompiler extends DevStudioCompatibleCCompiler { + private static final IntelWin64CCompiler instance = new IntelWin64CCompiler( + false, null); + public static IntelWin64CCompiler getInstance() { + return instance; + } + private IntelWin64CCompiler(boolean newEnvironment, Environment env) { + super("ecl", "-help", newEnvironment, env); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new IntelWin64CCompiler(newEnvironment, env); + } + return this; + } + public Linker getLinker(LinkType type) { + // + // currently the Intel Win32 and Win64 linkers + // are command line equivalent + return IntelWin32Linker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return 32767; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java new file mode 100644 index 0000000..32eb9ec --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/XpidlCompiler.java @@ -0,0 +1,365 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.mozilla; + +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.OptimizationEnum; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor; +import net.sf.antcontrib.cpptasks.gcc.LdLinker; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; + +/** + * Adapter for the Mozilla Xpidl Compiler. + * + * @author Curt Arnold + */ +public final class XpidlCompiler + extends CommandLineCompiler { + /** + * Singleton instance. + */ + private static final XpidlCompiler INSTANCE = new XpidlCompiler( + false, null); + /** + * Gets singleton instance of compiler. + * @return XpidlCompiler singleton instance + */ + public static XpidlCompiler getInstance() { + return INSTANCE; + } + + /** + * Constructor. + * @param newEnvironment boolean establish an new environment. + * @param env Environment environment. + */ + private XpidlCompiler(final boolean newEnvironment, + final Environment env) { + super("xpidl", null, new String[] {".idl", ".xpidl"} + , new String[0], ".xpt", false, null, newEnvironment, env); + } + + /** + * Add arguments for debug, etc. + * @param args Vector command argument list + * @param debug boolean build for debug if true + * @param multithreaded boolean build for multithreading if true + * @param exceptions boolean enable exceptions if true + * @param linkType LinkType output and runtime type + * @param rtti Boolean enable run-time type identification if true + * @param optimization OptimizationEnum optimization + */ + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + } + + /** + * Add arguments for specified warning level. + * @param args Vector command line arguments + * @param level int warning level value + */ + protected void addWarningSwitch(final Vector args, + final int level) { + } + + /** + * Change enviroment (deprecated). + * @param newEnvironment boolean use new environment. + * @param env Environment environment + * @return Processor modified processor + */ + public Processor changeEnvironment(final boolean newEnvironment, + final Environment env) { + return this; + } + + /** + * Gets dependency parser. + * @param source source file + * @return parser + */ + protected Parser createParser(final File source) { + return new CParser(); + } + + /** + * Gets number of command line arguments per input file. + * @return int number of command line arguments per input file. + */ + protected int getArgumentCountPerInputFile() { + return 3; + } + + /** + * Gets output file names. + * @param inputFile String input file name + * @param versionInfo version info, not used by this compiler. + * @return String[] output file names + */ + public String[] getOutputFileNames(final String inputFile, + final VersionInfo versionInfo) { + // + // if a recognized input file + // + String baseName = getBaseOutputName(inputFile); + return new String[] { + baseName + ".xpt", + baseName + ".h"}; + } + + /** + * Gets input file arguments. + * @param outputDir File output directory + * @param filename String input file name. + * @param index int argument index, + * 0 to getNumberOfArgumentsPerInputFile() -1 + * @return String input file argument + */ + protected String getInputFileArgument(final File outputDir, + final String filename, + final int index) { + return ""; + } + + /** + * Gets maximum length of command line. + * @return int maximum length of command line + */ + public int getMaximumCommandLength() { + return 1024; + } + + /** + * Gets maximum number of input files processed per command. + * @return int maximum number of input files processed per command. + */ + protected int getMaximumInputFilesPerCommand() { + return 1; + } + + /** + * Adds command line arguments for include paths. + * + * @param baseDirPath String base directory + * @param includeDirs File[] include directories + * @param args Vector command line arguments + * @param relativeArgs Vector arguments for configuration identification + * @param includePathId StringBuffer buffer for configuration identification + */ + protected void addIncludes(final String baseDirPath, + final File[] includeDirs, + final Vector args, + final Vector relativeArgs, + final StringBuffer includePathId) { + // + // requires space between switch and path + // + for (int i = 0; i < includeDirs.length; i++) { + args.addElement("-I"); + args.addElement(includeDirs[i].getAbsolutePath()); + if (relativeArgs != null) { + String relative = CUtil.getRelativePath(baseDirPath, + includeDirs[i]); + relativeArgs.addElement("-I"); + relativeArgs.addElement(relative); + if (includePathId != null) { + if (includePathId.length() == 0) { + includePathId.append("-I "); + } else { + includePathId.append(" -I "); + } + includePathId.append(relative); + } + } + } + } + + /** + * Gets include directory switch. + * @param includeDir String include directory + * @return String command switch to add specified directory to search path + */ + protected String getIncludeDirSwitch(final String includeDir) { + return "-I" + includeDir; + } + + /** + * Gets switch to define preprocessor macro. + * @param buffer StringBuffer command line argument + * @param define String macro name + * @param value String macro value, may be null. + */ + protected void getDefineSwitch(final StringBuffer buffer, + final String define, + final String value) { + } + + /** + * Gets switch to undefine preprocessor macro. + * @param buffer StringBuffer command line argument + * @param define String macro name + */ + protected void getUndefineSwitch(final StringBuffer buffer, + final String define) { + } + + /** + * Gets standard include paths. + * @return File[] standard include paths + */ + protected File[] getEnvironmentIncludePath() { + return new File[0]; + } + + /** + * Gets linker associated with this type. + * @param type LinkType linker, returns ld. + * @return Linker + */ + public Linker getLinker(final LinkType type) { + return LdLinker.getInstance(); + } + + /** + * Compiles an .idl file into the corresponding .h and .xpt files. + * @param task current cc task + * @param outputDir output directory + * @param sourceFiles source files + * @param args command line arguments that appear before input files + * @param endArgs command line arguments that appear after input files + * @param relentless if true, do not stop at first compilation error + * @param config compiler configuration + * @param monitor progress monitor + */ + public void compile(final CCTask task, + final File outputDir, + final String[] sourceFiles, + final String[] args, + final String[] endArgs, + final boolean relentless, + final CommandLineCompilerConfiguration config, + final ProgressMonitor monitor) { + + BuildException exc = null; + String[] thisSource = new String[1]; + String[] tlbCommand = new String[args.length + endArgs.length + 6]; + tlbCommand[0] = "xpidl"; + tlbCommand[1] = "-m"; + tlbCommand[2] = "typelib"; + String[] headerCommand = new String[args.length + endArgs.length + 6]; + headerCommand[0] = "xpidl"; + headerCommand[1] = "-m"; + headerCommand[2] = "header"; + for (int i = 0; i < args.length; i++) { + tlbCommand[i + 3] = args[i]; + headerCommand[i + 3] = args[i]; + } + tlbCommand[args.length + 3] = "-e"; + headerCommand[args.length + 3] = "-e"; + + int tlbIndex = args.length + 6; + int headerIndex = args.length + 6; + for (int i = 0; i < endArgs.length; i++) { + tlbCommand[tlbIndex++] = endArgs[i]; + headerCommand[headerIndex++] = endArgs[i]; + } + for (int j = 0; j < sourceFiles.length; j++) { + tlbIndex = args.length + 4; + headerIndex = args.length + 4; + String[] outputFileNames = getOutputFileNames(sourceFiles[j], null); + + tlbCommand[tlbIndex++] = outputFileNames[0]; + tlbCommand[tlbIndex++] = sourceFiles[j]; + + headerCommand[headerIndex++] = outputFileNames[1]; + headerCommand[headerIndex++] = sourceFiles[j]; + + int retval = runCommand(task, outputDir, tlbCommand); + if (retval == 0) { + retval = runCommand(task, outputDir, headerCommand); + } + if (monitor != null) { + thisSource[0] = sourceFiles[j]; + monitor.progress(thisSource); + } + // + // if the process returned a failure code and + // we aren't holding an exception from an earlier + // interation + if (retval != 0 && exc == null) { + // + // construct the exception + // + exc = new BuildException(this.getCommand() + + " failed with return code " + retval, task + .getLocation()); + // + // and throw it now unless we are relentless + // + if (!relentless) { + throw exc; + } + } + } + // + // if the compiler returned a failure value earlier + // then throw an exception + if (exc != null) { + throw exc; + } + } + + /** + * Get total command line length due to the input file. + * @param outputDir File output directory + * @param inputFile String input file + * @return int characters added to command line for the input file. + */ + protected int getTotalArgumentLengthForInputFile( + final File outputDir, + final String inputFile) { + return 0; + } + + /** + * Gets compiler identifier. + * @return String compiler identification string + */ + public String getIdentifier() { + return "Mozilla xpidl"; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html new file mode 100644 index 0000000..6be6dff --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/mozilla/package.html @@ -0,0 +1,27 @@ + + + + + + + +Compiler adapter for Mozilla's XPCOM compiler. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java new file mode 100644 index 0000000..4c36438 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCCompiler.java @@ -0,0 +1,84 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import java.io.File; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.types.Environment; + +/** + * Adapter for the OpenWatcom C Compiler. + * + * @author Curt Arnold + */ +public final class OpenWatcomCCompiler + extends OpenWatcomCompiler { + /** + * Singleton. + */ + private static final OpenWatcomCCompiler INSTANCE = new OpenWatcomCCompiler( + "wcl386", + false, null); + + /** + * Get compiler. + * @return OpenWatcomCCompiler compiler + */ + public static OpenWatcomCCompiler getInstance() { + return INSTANCE; + } + + /** + * Constructor. + * @param command String command + * @param newEnvironment boolean use new environment + * @param env Environment environment + */ + private OpenWatcomCCompiler(final String command, + final boolean newEnvironment, + final Environment env) { + super(command, "/?", + new String[] {".c", ".cc", ".cpp", ".cxx", ".c++"} + , + new String[] {".h", ".hpp", ".inl"} + , + newEnvironment, env); + } + + /** + * Create parser. + * @param source File file to be parsed. + * @return Parser parser + */ + public Parser createParser(final File source) { + return new CParser(); + } + + /** + * Get linker. + * @param type link type + * @return linker + */ + public Linker getLinker(final LinkType type) { + return OpenWatcomCLinker.getInstance().getLinker(type); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java new file mode 100644 index 0000000..93e65b4 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCLinker.java @@ -0,0 +1,69 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; + +/** + * Adapter for the OpenWatcom linker. + * + * @author Curt Arnold + */ +public final class OpenWatcomCLinker + extends OpenWatcomLinker { + /** + * Dll linker. + */ + private static final OpenWatcomCLinker DLL_LINKER = + new OpenWatcomCLinker(".dll"); + /** + * Exe linker. + */ + private static final OpenWatcomCLinker INSTANCE = + new OpenWatcomCLinker(".exe"); + /** + * Get linker instance. + * @return OpenWatcomCLinker linker + */ + public static OpenWatcomCLinker getInstance() { + return INSTANCE; + } + + /** + * Constructor. + * @param outputSuffix String output suffix. + */ + private OpenWatcomCLinker(final String outputSuffix) { + super("wcl386", outputSuffix); + } + + /** + * Get linker. + * @param type LinkType link type + * @return Linker linker + */ + public Linker getLinker(final LinkType type) { + if (type.isStaticLibrary()) { + return OpenWatcomLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return DLL_LINKER; + } + return INSTANCE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java new file mode 100644 index 0000000..4cf2d18 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomCompiler.java @@ -0,0 +1,169 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.OptimizationEnum; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Processor; + +import org.apache.tools.ant.types.Environment; + +/** + * An abstract base class for the OpenWatcom C and Fortran compilers. + * + * @author Curt Arnold + */ +public abstract class OpenWatcomCompiler + extends CommandLineCompiler { + /** + * Constructor. + * @param command String command + * @param identifierArg String identifier + * @param sourceExtensions String[] source extension + * @param headerExtensions String[] header extension + * @param newEnvironment boolean use new enviroment + * @param env Environment environment + */ + protected OpenWatcomCompiler(final String command, + final String identifierArg, + final String[] sourceExtensions, + final String[] headerExtensions, + final boolean newEnvironment, + final Environment env) { + super(command, identifierArg, sourceExtensions, + headerExtensions, ".obj", false, + null, newEnvironment, env); + } + + /** + * Add implied arguments. + * @param args Vector command line arguments + * @param debug boolean is debug + * @param multithreaded boolean multithreaderd + * @param exceptions boolean support exceptions + * @param linkType LinkType link type + * @param rtti Boolean run time type information + * @param optimization OptimizationEnum + */ + protected final void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("/c"); + if (exceptions) { + args.addElement("/xs"); + } + if (multithreaded) { + args.addElement("/bm"); + } + if (debug) { + args.addElement("/d2"); + args.addElement("/od"); + args.addElement("/d_DEBUG"); + } else { + if (optimization != null) { + if (optimization.isSize()) { + args.addElement("/os"); + } + if (optimization.isSpeed()) { + args.addElement("/ot"); + } + } + args.addElement("/dNDEBUG"); + } + if (rtti != null && rtti.booleanValue()) { + args.addElement("/xr"); + } + } + + /** + * Add warning switch. + * @param args Vector command line arguments + * @param level int warning level + */ + protected final void addWarningSwitch(final Vector args, final int level) { + OpenWatcomProcessor.addWarningSwitch(args, level); + } + + /** + * Change enviroment. + * @param newEnvironment boolean use new enviroment + * @param env Environment environment + * @return Processor modified processor + */ + public final Processor changeEnvironment(final boolean newEnvironment, + final Environment env) { + return this; + } + + /** + * Get define switch. + * @param buffer StringBuffer buffer + * @param define String preprocessor macro + * @param value String value, may be null. + */ + protected final void getDefineSwitch(final StringBuffer buffer, + final String define, + final String value) { + OpenWatcomProcessor.getDefineSwitch(buffer, define, value); + } + + /** + * Get include path from environment. + * @return File[] + */ + protected final File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ";"); + } + + /** + * Get include directory switch. + * @param includeDir String include directory + * @return String command line argument + */ + protected final String getIncludeDirSwitch(final String includeDir) { + return OpenWatcomProcessor.getIncludeDirSwitch(includeDir); + } + + + /** + * Get maximum command line length. + * @return int maximum command line length + */ + public final int getMaximumCommandLength() { + return 4096; + } + + /** + * Get undefine switch. + * @param buffer StringBuffer argument destination + * @param define String preprocessor macro + */ + protected final void getUndefineSwitch(final StringBuffer buffer, + final String define) { + OpenWatcomProcessor.getUndefineSwitch(buffer, define); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java new file mode 100644 index 0000000..ca3abcb --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranCompiler.java @@ -0,0 +1,86 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import java.io.File; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.parser.FortranParser; +import net.sf.antcontrib.cpptasks.parser.Parser; + +import org.apache.tools.ant.types.Environment; + +/** + * Adapter for the OpenWatcom Fortran compiler. + * + * @author Curt Arnold + */ +public final class OpenWatcomFortranCompiler + extends OpenWatcomCompiler { + /** + * Singleton. + */ + private static final OpenWatcomFortranCompiler[] INSTANCE = + new OpenWatcomFortranCompiler[] { + new OpenWatcomFortranCompiler( + "wfl386", false, null)}; + + /** + * Get instance. + * @return OpenWatcomFortranCompiler compiler instance + */ + public static OpenWatcomFortranCompiler getInstance() { + return INSTANCE[0]; + } + + /** + * Constructor. + * @param command String command + * @param newEnvironment boolean use new environment + * @param env Environment environment + */ + private OpenWatcomFortranCompiler(final String command, + final boolean newEnvironment, + final Environment env) { + super(command, "/?", + new String[] {".f90", ".for", ".f"} + , + new String[] {".i", ".i90", ".fpp"} + , + newEnvironment, env); + } + + /** + * Create dependency parser. + * @param source File source file + * @return Parser parser + */ + public Parser createParser(final File source) { + return new FortranParser(); + } + + /** + * Get linker. + * @param type link type + * @return linker + */ + public Linker getLinker(final LinkType type) { + return OpenWatcomFortranLinker.getInstance().getLinker(type); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java new file mode 100644 index 0000000..82b6999 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomFortranLinker.java @@ -0,0 +1,69 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; + +/** + * Adapter for the OpenWatcom Fortran linker. + * + * @author Curt Arnold + */ +public final class OpenWatcomFortranLinker + extends OpenWatcomLinker { + /** + * Singleton for DLL linking. + */ + private static final OpenWatcomFortranLinker DLL_LINKER = new + OpenWatcomFortranLinker(".dll"); + /** + * Singleton for executables. + */ + private static final OpenWatcomFortranLinker INSTANCE = new + OpenWatcomFortranLinker(".exe"); + /** + * Get instance. + * @return OpenWatcomFortranLinker linker + */ + public static OpenWatcomFortranLinker getInstance() { + return INSTANCE; + } + + /** + * Constructor. + * @param outputSuffix String output suffix + */ + private OpenWatcomFortranLinker(final String outputSuffix) { + super("wfl386", outputSuffix); + } + + /** + * Get linker. + * @param type LinkType link type + * @return Linker linker + */ + public Linker getLinker(final LinkType type) { + if (type.isStaticLibrary()) { + return OpenWatcomLibrarian.getInstance(); + } + if (type.isSharedLibrary()) { + return DLL_LINKER; + } + return INSTANCE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java new file mode 100644 index 0000000..848c395 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLibrarian.java @@ -0,0 +1,254 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for the OpenWatcom Librarian. + * + * @author Curt Arnold + */ +public final class OpenWatcomLibrarian + extends CommandLineLinker { + /** + * Singleton. + */ + private static final OpenWatcomLibrarian INSTANCE = new OpenWatcomLibrarian(); + /** + * Singleton accessor. + * @return OpenWatcomLibrarian librarian instance + */ + public static OpenWatcomLibrarian getInstance() { + return INSTANCE; + } + + /** + * Constructor. + */ + private OpenWatcomLibrarian() { + super("wlib", null, new String[] {".obj"} + , new String[0], ".lib", false, + null); + } + + /** + * Add base address. + * @param base long base address + * @param args Vector command line arguments + */ + protected void addBase(final long base, final Vector args) { + } + + /** + * Add alternative entry point. + * @param entry String entry point + * @param args Vector command line arguments + */ + protected void addEntry(final String entry, final Vector args) { + } + + /** + * Add fixed parameter. + * @param fixed Boolean true if fixed + * @param args Vector command line arguments + */ + protected void addFixed(final Boolean fixed, final Vector args) { + } + + /** + * Add implied arguments. + * @param debug boolean true if debugging + * @param linkType LinkType link type + * @param args Vector command line arguments + */ + protected void addImpliedArgs(final boolean debug, + final LinkType linkType, + final Vector args) { + } + + /** + * Add incremental option. + * @param incremental boolean true if incremental + * @param args Vector command line arguments + */ + protected void addIncremental(final boolean incremental, + final Vector args) { + } + + /** + * Add map option. + * @param map boolean true to create map file + * @param args Vector command line argument + */ + protected void addMap(final boolean map, + final Vector args) { + } + + /** + * Add stack size option. + * @param stack int stack size + * @param args Vector command line arguments + */ + protected void addStack(final int stack, + final Vector args) { + } + + /** + * Get command file switch. + * @param cmdFile String command file + * @return String command file switch + */ + protected String getCommandFileSwitch(final String cmdFile) { + return OpenWatcomProcessor.getCommandFileSwitch(cmdFile); + } + + + /** + * Get library search path. + * @return File[] library search path + */ + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + + /** + * Get file selectors for specified library names. + * @param libnames String[] library names + * @param libType LibraryTypeEnum library type enum + * @return String[] file selection patterns + */ + public String[] getLibraryPatterns(final String[] libnames, + final LibraryTypeEnum libType) { + return OpenWatcomProcessor.getLibraryPatterns(libnames, libType); + } + + /** + * Get linker. + * @param type LinkType link type + * @return Linker linker + */ + public Linker getLinker(final LinkType type) { + return OpenWatcomCLinker.getInstance().getLinker(type); + } + + /** + * Gets maximum command line. + * @return int maximum command line + */ + public int getMaximumCommandLength() { + return 1024; + } + + /** + * Create output file switch. + * @param outFile String output file switch + * @return String[] output file switch + */ + public String[] getOutputFileSwitch(final String outFile) { + return OpenWatcomProcessor.getOutputFileSwitch(outFile); + } + + /** + * Gets case-sensisitivity of processor. + * @return boolean true if case sensitive + */ + public boolean isCaseSensitive() { + return OpenWatcomProcessor.isCaseSensitive(); + } + + /** + * Builds a library. + * @param task task + * @param outputFile generated library + * @param sourceFiles object files + * @param config linker configuration + */ + public void link(final CCTask task, + final File outputFile, + final String[] sourceFiles, + final CommandLineLinkerConfiguration config) { + // + // delete any existing library + outputFile.delete(); + // + // build a new library + super.link(task, outputFile, sourceFiles, config); + } + + /** + * Prepares argument list for exec command. + * @param task task + * @param outputDir output directory + * @param outputName output file name + * @param sourceFiles object files + * @param config linker configuration + * @return arguments for runTask + */ + protected String[] prepareArguments( + final CCTask task, + final String outputDir, + final String outputName, + final String[] sourceFiles, + final CommandLineLinkerConfiguration config) { + String[] preargs = config.getPreArguments(); + String[] endargs = config.getEndArguments(); + StringBuffer buf = new StringBuffer(); + Vector execArgs = new Vector(preargs.length + endargs.length + 10 + + sourceFiles.length); + + execArgs.addElement(this.getCommand()); + String outputFileName = new File(outputDir, outputName).toString(); + execArgs.addElement(quoteFilename(buf, outputFileName)); + + for (int i = 0; i < preargs.length; i++) { + execArgs.addElement(preargs[i]); + } + + int objBytes = 0; + + for (int i = 0; i < sourceFiles.length; i++) { + String last4 = sourceFiles[i] + .substring(sourceFiles[i].length() - 4).toLowerCase(); + if (!last4.equals(".def") + && !last4.equals(".res") + && !last4.equals(".lib")) { + execArgs.addElement("+" + quoteFilename(buf, sourceFiles[i])); + objBytes += new File(sourceFiles[i]).length(); + } + } + + for (int i = 0; i < endargs.length; i++) { + execArgs.addElement(endargs[i]); + } + + String[] execArguments = new String[execArgs.size()]; + execArgs.copyInto(execArguments); + + return execArguments; + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java new file mode 100644 index 0000000..f0bbe3d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomLinker.java @@ -0,0 +1,205 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import java.io.File; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.platforms.WindowsPlatform; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for the OpenWatcom linker. + * + * @author Curt Arnold + */ +public abstract class OpenWatcomLinker + extends CommandLineLinker { + /** + * Constructor. + * @param command String command string (wcl386 or wfl386) + * @param outputSuffix String output suffix + */ + protected OpenWatcomLinker(final String command, + final String outputSuffix) { + super(command, "-r", new String[] {".obj", ".lib", ".res"} + , + new String[] {".map", ".pdb", ".lnk"} + , outputSuffix, false, null); + } + + /** + * Add specified base address to linker options. + * @param base long base address + * @param args Vector command options + */ + protected final void addBase(final long base, final Vector args) { + } + + /** + * Adds non-default entry point. + * @param entry entry point name + * @param args command line parameters + */ + protected final void addEntry(final String entry, final Vector args) { + } + + /** + * Adds fixed option. + * @param fixed if executable is fixed + * @param args command line parameters + */ + protected final void addFixed(final Boolean fixed, final Vector args) { + } + + /** + * Adds other command line parameters. + * @param debug boolean is debug + * @param linkType LinkType link type + * @param args Vector command line arguments + */ + protected final void addImpliedArgs(final boolean debug, + final LinkType linkType, + final Vector args) { + if (linkType.isExecutable()) { + if (linkType.isSubsystemConsole()) { + args.addElement("/bc"); + } else { + if (linkType.isSubsystemGUI()) { + args.addElement("/bg"); + } + } + } + if (linkType.isSharedLibrary()) { + args.addElement("/bd"); + } + } + + /** + * Add command line switch to force incremental linking. + * @param incremental boolean do incremental linking + * @param args Vector command line arguments + */ + protected final void addIncremental(final boolean incremental, + final Vector args) { + } + + /** + * Add command line switch to force map generation. + * @param map boolean build map + * @param args Vector command line arguments + */ + protected final void addMap(final boolean map, final Vector args) { + if (map) { + args.addElement("/fm"); + } + } + + /** + * Add command line switch for stack reservation. + * @param stack int stack size. + * @param args Vector command line arguments. + */ + protected final void addStack(final int stack, final Vector args) { + if (stack >= 0) { + String stackStr = Integer.toString(stack); + args.addElement("/k" + stackStr); + } + } + + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + * @throws IOException if unable to write version resource + */ + public final void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) throws IOException { + WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, + objDir, matcher); + } + + /** + * Get command file switch. + * @param commandFile String command file name + * @return String command line option + */ + public final String getCommandFileSwitch(final String commandFile) { + return "@" + commandFile; + } + + /** + * Get search path for libraries. + * @return File[] library path + */ + public final File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + + /** + * Get file selectors for libraries. + * @param libnames String[] + * @param libType LibraryTypeEnum + * @return String[] + */ + public final String[] getLibraryPatterns(final String[] libnames, + final LibraryTypeEnum libType) { + return OpenWatcomProcessor.getLibraryPatterns(libnames, libType); + } + + /** + * Get maximum command line length. + * @return int command line length + */ + public final int getMaximumCommandLength() { + return 1024; + } + + /** + * Get output file switch. + * @param outFile Output file name + * @return String[] command line switches + */ + public final String[] getOutputFileSwitch(final String outFile) { + return OpenWatcomProcessor.getOutputFileSwitch(outFile); + } + + /** + * Gets file name sensitivity of processors. + * @return boolean true if case sensitive. + */ + public final boolean isCaseSensitive() { + return OpenWatcomProcessor.isCaseSensitive(); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java new file mode 100644 index 0000000..5845776 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/OpenWatcomProcessor.java @@ -0,0 +1,169 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.openwatcom; + +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * A add-in class for OpenWatcom processors. + * + * + */ +public final class OpenWatcomProcessor { + /** + * Adds warning command line options. + * + * @param args Vector list of options + * @param level int value of WarningLevelEnum + */ + public static void addWarningSwitch(final Vector args, final int level) { + switch (level) { + case 0: + args.addElement("/w0"); + break; + case 1: + args.addElement("/w1"); + break; + case 2: + break; + case 3: + args.addElement("/w2"); + break; + case 4: + args.addElement("/w3"); + break; + case 5: + args.addElement("/we"); + break; + default: + args.addElement("/w1"); + break; + } + } + + /** + * Gets command line option to read from an option file. + * + * @param cmdFile String file name for option file + * @return String Command line option + */ + public static String getCommandFileSwitch(final String cmdFile) { + StringBuffer buf = new StringBuffer("@"); + if (cmdFile.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(cmdFile.replace('/', '\\')); + buf.append('\"'); + } else { + buf.append(cmdFile); + } + return buf.toString(); + } + + /** + * Creates a command line option to define a preprocessor macro. + * + * @param buffer StringBuffer destination buffer + * @param define String parameter to define + * @param value String value, may be null + */ + public static void getDefineSwitch(final StringBuffer buffer, + final String define, + final String value) { + buffer.append("/d"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + + /** + * Create a command line option to add a directory to the include path. + * @param includeDir String directory + * @return String command line option + */ + public static String getIncludeDirSwitch(final String includeDir) { + return "/i=" + includeDir.replace('/', '\\'); + } + + /** + * Builds command line options to specify the output file names. + * + * @param outPath String path to output file + * @return String[] command line options + */ + public static String[] getOutputFileSwitch(final String outPath) { + StringBuffer buf = new StringBuffer("/fo="); + if (outPath.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + String[] retval = new String[] { + buf.toString()}; + return retval; + } + + /** + * Get file selectors for specified libraries. + * @param libnames library names + * @param libType library type + * @return file selectors + */ + public static String[] getLibraryPatterns(final String[] libnames, + final LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length]; + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(libnames[i]); + buf.append(".lib"); + patterns[i] = buf.toString(); + } + return patterns; + } + + /** + * Builds a command line option to undefine a preprocessor macro. + * @param buffer StringBuffer destination + * @param define String macro to be undefined + */ + public static void getUndefineSwitch(final StringBuffer buffer, + final String define) { + buffer.append("/u"); + buffer.append(define); + } + + /** + * Gets whether processor tratement of file names is case-sensitive. + * @return boolean true if case sensitive + */ + public static boolean isCaseSensitive() { + return false; + } + + /** + * Private constructor. + */ + private OpenWatcomProcessor() { + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html new file mode 100644 index 0000000..3d9adab --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/openwatcom/package.html @@ -0,0 +1,27 @@ + + + + + + + +Adapters for OpenWatcom compilers and tools. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java new file mode 100644 index 0000000..6b1895f --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java @@ -0,0 +1,156 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.os390; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.CompilerDef; +import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.types.DefineArgument; +import net.sf.antcontrib.cpptasks.types.UndefineArgument; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the IBM (R) OS/390 (tm) C++ Compiler + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public class OS390CCompiler extends CommandLineCCompiler { + private static final AbstractCompiler instance = new OS390CCompiler(false, + null); + public static AbstractCompiler getInstance() { + return instance; + } + private OS390CCompiler(boolean newEnvironment, Environment env) { + super("cxx", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++", + ".s"}, new String[]{".h", ".hpp"}, ".o", false, null, + newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + // Specifies that only compilations and assemblies be done. + // Link-edit is not done + args.addElement("-c"); + args.addElement("-W"); + args.addElement("c,NOEXPMAC,NOSHOWINC"); + /* + * if (exceptions) { args.addElement("/GX"); } + */ + if (debug) { + args.addElement("-g"); + args.addElement("-D"); + args.addElement("_DEBUG"); + /* + * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) { + * args.addElement("/MTd"); } else { args.addElement("/MDd"); + * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); } + */ + } else { + args.addElement("-D"); + args.addElement("NEBUG"); + /* + * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) { + * args.addElement("/MT"); } else { args.addElement("/MD"); + * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); } + */ + } + } + protected void addWarningSwitch(Vector args, int level) { + OS390Processor.addWarningSwitch(args, level); + } + /** + * The buildDefineArguments implementation CommandLineCCompiler is not good + * for us because os390 defines are give by -D definex instead of + * /Ddefinex, 2 args not 1! since we implement this ourslefs, we do not + * have to implement the getDefineSwitch() and the getUndefineSwitch(). + */ + protected void buildDefineArguments(CompilerDef[] defs, Vector args) { + // + // assume that we aren't inheriting defines from containing + // + UndefineArgument[] merged = defs[0].getActiveDefines(); + for (int i = 1; i < defs.length; i++) { + // + // if we are inheriting, merge the specific defines with the + // containing defines + merged = DefineArgument.merge(defs[i].getActiveDefines(), merged); + } + StringBuffer buf = new StringBuffer(30); + for (int i = 0; i < merged.length; i++) { + buf.setLength(0); + UndefineArgument current = merged[i]; + if (current.isDefine()) { + args.addElement("-D"); + buf.append(current.getName()); + if (current.getValue() != null + && current.getValue().length() > 0) { + buf.append('='); + buf.append(current.getValue()); + } + args.addElement(buf.toString()); + } else { + args.addElement("-U"); + args.addElement(current.getName()); + } + } + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new OS390CCompiler(newEnvironment, env); + } + return this; + } + /* + * @see CommandLineCompiler#getDefineSwitch(StringBuffer, String, String) + */ + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ":"); + } + protected String getIncludeDirSwitch(String includeDir) { + return OS390Processor.getIncludeDirSwitch(includeDir); + } + public Linker getLinker(LinkType type) { + return OS390Linker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + /* Only compile one file at time for now */ + protected int getMaximumInputFilesPerCommand() { + return Integer.MAX_VALUE; + } + /* + * @see CommandLineCompiler#getUndefineSwitch(StringBuffer, String) + */ + protected void getUndefineSwitch(StringBuffer buffer, String define) { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java new file mode 100644 index 0000000..9c4f845 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Linker.java @@ -0,0 +1,208 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.os390; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +/** + * Adapter for the IBM (R) OS/390 (tm) Linker + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public final class OS390Linker extends CommandLineLinker { + private static final OS390Linker datasetLinker = new OS390Linker(); + private static final OS390Linker dllLinker = new OS390Linker("", ".dll"); + private static final OS390Linker instance = new OS390Linker("", ""); + public static OS390Linker getDataSetInstance() { + return datasetLinker; + } + public static OS390Linker getInstance() { + return instance; + } + private boolean isADatasetLinker; + File outputFile; + private String outputPrefix; + CCTask task; + private OS390Linker() { + super("cxx", "/bogus", new String[]{".o", ".a", ".lib", ".xds"}, + new String[]{".dll", ".x"}, ".xds", false, null); + this.outputPrefix = ""; + this.isADatasetLinker = true; + } + private OS390Linker(String outputPrefix, String outputSuffix) { + super("cxx", "/bogus", new String[]{".o", ".a", ".lib", ".x"}, + new String[]{".dll"}, outputSuffix, false, null); + this.outputPrefix = outputPrefix; + this.isADatasetLinker = false; + } + protected void addBase(long base, Vector args) { + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (linkType.isSharedLibrary()) { + args.addElement("-W"); + args.addElement("l,DLL"); + } + } + protected void addIncremental(boolean incremental, Vector args) { + } + /* + * @see CommandLineLinker#addLibrarySets(LibrarySet[], Vector, Vector, + * Vector) + */ + protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + // If yo want to link against a library sitting in a dataset and + // not in the HFS, you can just use the //'dataset' notation + // to specify it. e.g: + // + // + // We have to have special handling here because the file is not + // on the normal filesystem so the task will not noramly include it + // as part of the link command. + if (libsets != null) { + for (int i = 0; i < libsets.length; i++) { + String libs[] = libsets[i].getLibs(); + for (int j = 0; j < libs.length; j++) { + if (libs[j].startsWith("//")) { + endargs.addElement("-l"); + endargs.addElement(libs[j]); + } else if (libsets[i].getDataset() != null) { + String ds = libsets[i].getDataset(); + endargs.addElement("//'" + ds + "(" + libs[j] + ")'"); + } + } + } + } + return super.addLibrarySets(task, libsets, preargs, midargs, endargs); + } + protected void addMap(boolean map, Vector args) { + } + protected void addStack(int stack, Vector args) { + } + protected void addEntry(String entry, Vector args) { + } + + public String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length * 3]; + int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + offset = addLibraryPatterns(libnames, buf, "", ".x", patterns, offset); + offset = addLibraryPatterns(libnames, buf, "", ".o", patterns, offset); + return patterns; + } + + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + + public Linker getLinker(LinkType linkType) { + if (this == datasetLinker) + return datasetLinker; + if (linkType.isSharedLibrary()) + return dllLinker; + return instance; + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + String[] baseNames = super.getOutputFileNames(baseName, versionInfo); + if (outputPrefix.length() > 0) { + for(int i = 0; i < baseNames.length; i++) { + baseNames[i] = outputPrefix + baseNames[i]; + } + } + return baseNames; + } + protected String[] getOutputFileSwitch(CCTask task, String outputFile) { + if (isADatasetLinker && task.getDataset() != null) { + String ds = task.getDataset(); + outputFile = "//'" + ds + "(" + outputFile + ")'"; + } + return getOutputFileSwitch(outputFile); + } + public String[] getOutputFileSwitch(String outputFile) { + return new String[]{"-o", outputFile}; + } + public boolean isCaseSensitive() { + return OS390Processor.isCaseSensitive(); + } + /* + * @see CommandLineLinker#link(Task, File, String[], + * CommandLineLinkerConfiguration) + */ + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + this.task = task; + this.outputFile = outputFile; + if (isADatasetLinker) { + int p = outputFile.getName().indexOf("."); + if (p >= 0) { + String newname = outputFile.getName().substring(0, p); + outputFile = new File(outputFile.getParent(), newname); + } + } + super.link(task, outputFile, sourceFiles, config); + } + /* + * @see CommandLineLinker#runCommand(Task, File, String[]) + */ + protected int runCommand(CCTask task, File workingDir, String[] cmdline) + throws BuildException { + int rc = super.runCommand(task, workingDir, cmdline); + // create the .xds file if everything was ok. + if (rc == 0) { + try { + outputFile.delete(); + new FileOutputStream(outputFile).close(); + } catch (IOException e) { + throw new BuildException(e.getMessage()); + } + } + return rc; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java new file mode 100644 index 0000000..d3243fc --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/os390/OS390Processor.java @@ -0,0 +1,71 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.os390; +import java.util.Vector; +/** + * A add-in class for IBM (r) OS/390 compilers and linkers + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public class OS390Processor { + public static void addWarningSwitch(Vector args, int level) { + switch (level) { + /* + * case 0: args.addElement("/W0"); break; + * + * case 1: args.addElement("/W1"); break; + * + * case 2: break; + * + * case 3: args.addElement("/W3"); break; + * + * case 4: args.addElement("/W4"); break; + */ + } + } + public static String getCommandFileSwitch(String cmdFile) { + StringBuffer buf = new StringBuffer("@"); + if (cmdFile.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(cmdFile); + buf.append('\"'); + } else { + buf.append(cmdFile); + } + return buf.toString(); + } + public static String getIncludeDirSwitch(String includeDir) { + return "-I" + includeDir; + } + public static String[] getOutputFileSwitch(String outPath) { + StringBuffer buf = new StringBuffer("-o "); + if (outPath.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + String[] retval = new String[]{buf.toString()}; + return retval; + } + public static boolean isCaseSensitive() { + return true; + } + private OS390Processor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java new file mode 100644 index 0000000..952d719 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccCompiler.java @@ -0,0 +1,123 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.os400; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the IBM (R) OS/390 (tm) C++ Compiler + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public class IccCompiler extends CommandLineCCompiler { + private static final AbstractCompiler instance = new IccCompiler(false, + null); + public static AbstractCompiler getInstance() { + return instance; + } + private IccCompiler(boolean newEnvironment, Environment env) { + super("icc", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++", + ".s"}, new String[]{".h", ".hpp"}, ".o", false, null, + newEnvironment, env); + } + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + // Specifies that only compilations and assemblies be done. + // Link-edit is not done + args.addElement("-c"); + /* + * if (exceptions) { args.addElement("/GX"); } + */ + if (debug) { + args.addElement("-g"); + /* + * args.addElement("-D"); args.addElement("_DEBUG"); if + * (multithreaded) { args.addElement("/D_MT"); if (staticLink) { + * args.addElement("/MTd"); } else { args.addElement("/MDd"); + * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); } + */ + } else { + /* + * args.addElement("-D"); args.addElement("NEBUG"); if + * (multithreaded) { args.addElement("/D_MT"); if (staticLink) { + * args.addElement("/MT"); } else { args.addElement("/MD"); + * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); } + */ + } + } + protected void addWarningSwitch(Vector args, int level) { + IccProcessor.addWarningSwitch(args, level); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new IccCompiler(newEnvironment, env); + } + return this; + } + /* + * @see CommandLineCompiler#getDefineSwitch(StringBuffer, String, String) + */ + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("-q"); + buffer.append(define); + if (value != null && value.length() > 0) { + buffer.append('='); + buffer.append(value); + } + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ":"); + } + protected String getIncludeDirSwitch(String includeDir) { + return IccProcessor.getIncludeDirSwitch(includeDir); + } + public Linker getLinker(LinkType type) { + return IccLinker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + /* Only compile one file at time for now */ + protected int getMaximumInputFilesPerCommand() { + return 1; + //return Integer.MAX_VALUE; + } + /* + * @see CommandLineCompiler#getUndefineSwitch(StringBuffer, String) + */ + protected void getUndefineSwitch(StringBuffer buffer, String define) { + /* + * buffer.addElement("-q"); buf.append(define); + */ + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java new file mode 100644 index 0000000..ea10bcc --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccLinker.java @@ -0,0 +1,209 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.os400; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +import net.sf.antcontrib.cpptasks.VersionInfo; +import org.apache.tools.ant.BuildException; +/** + * Adapter for the IBM (R) OS/390 (tm) Linker + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public final class IccLinker extends CommandLineLinker { + private static final IccLinker datasetLinker = new IccLinker(); + private static final IccLinker dllLinker = new IccLinker("", ".dll"); + private static final IccLinker instance = new IccLinker("", ""); + public static IccLinker getDataSetInstance() { + return datasetLinker; + } + public static IccLinker getInstance() { + return instance; + } + private boolean isADatasetLinker; + File outputFile; + private String outputPrefix; + CCTask task; + private IccLinker() { + super("icc", "/bogus", new String[]{".o", ".a", ".lib", ".xds"}, + new String[]{".dll", ".x"}, ".xds", false, null); + this.outputPrefix = ""; + this.isADatasetLinker = true; + } + private IccLinker(String outputPrefix, String outputSuffix) { + super("icc", "/bogus", new String[]{".o", ".a", ".lib", ".x"}, + new String[]{".dll"}, outputSuffix, false, null); + this.outputPrefix = outputPrefix; + this.isADatasetLinker = false; + } + protected void addBase(long base, Vector args) { + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (linkType.isSharedLibrary()) { + args.addElement("-W"); + args.addElement("l,DLL"); + } + } + protected void addIncremental(boolean incremental, Vector args) { + } + /* + * @see CommandLineLinker#addLibrarySets(LibrarySet[], Vector, Vector, + * Vector) + */ + protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + // If yo want to link against a library sitting in a dataset and + // not in the HFS, you can just use the //'dataset' notation + // to specify it. e.g: + // + // + // We have to have special handling here because the file is not + // on the normal filesystem so the task will not noramly include it + // as part of the link command. + if (libsets != null) { + for (int i = 0; i < libsets.length; i++) { + String libs[] = libsets[i].getLibs(); + for (int j = 0; j < libs.length; j++) { + if (libs[j].startsWith("//")) { + endargs.addElement("-l"); + endargs.addElement(libs[j]); + } else if (libsets[i].getDataset() != null) { + String ds = libsets[i].getDataset(); + endargs.addElement("//'" + ds + "(" + libs[j] + ")'"); + } + } + } + } + return super.addLibrarySets(task, libsets, preargs, midargs, endargs); + } + protected void addMap(boolean map, Vector args) { + } + protected void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + public String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length * 3]; + int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + offset = addLibraryPatterns(libnames, buf, "", ".x", patterns, offset); + offset = addLibraryPatterns(libnames, buf, "", ".o", patterns, offset); + return patterns; + } + + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + + + public Linker getLinker(LinkType linkType) { + if (this == datasetLinker) + return datasetLinker; + if (linkType.isSharedLibrary()) + return dllLinker; + return instance; + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + protected String[] getOutputFileSwitch(CCTask task, String outputFile) { + if (isADatasetLinker && task.getDataset() != null) { + String ds = task.getDataset(); + outputFile = "//'" + ds + "(" + outputFile + ")'"; + } + return getOutputFileSwitch(outputFile); + } + public String[] getOutputFileSwitch(String outputFile) { + return new String[]{"-o", outputFile}; + } + public boolean isCaseSensitive() { + return IccProcessor.isCaseSensitive(); + } + /* + * @see CommandLineLinker#link(Task, File, String[], + * CommandLineLinkerConfiguration) + */ + public void link(CCTask task, File outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) throws BuildException { + this.task = task; + this.outputFile = outputFile; + if (isADatasetLinker) { + int p = outputFile.getName().indexOf("."); + if (p >= 0) { + String newname = outputFile.getName().substring(0, p); + outputFile = new File(outputFile.getParent(), newname); + } + } + super.link(task, outputFile, sourceFiles, config); + } + /* + * @see CommandLineLinker#runCommand(Task, File, String[]) + */ + protected int runCommand(CCTask task, File workingDir, String[] cmdline) + throws BuildException { + int rc = super.runCommand(task, workingDir, cmdline); + // create the .xds file if everything was ok. + if (rc == 0) { + try { + outputFile.delete(); + new FileOutputStream(outputFile).close(); + } catch (IOException e) { + throw new BuildException(e.getMessage()); + } + } + return rc; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + String[] baseNames = super.getOutputFileNames(baseName, versionInfo); + if (outputPrefix.length() > 0) { + for(int i = 0; i < baseNames.length; i++) { + baseNames[i] = outputPrefix + baseNames[i]; + } + } + return baseNames; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java new file mode 100644 index 0000000..f15aa8b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/os400/IccProcessor.java @@ -0,0 +1,71 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.os400; +import java.util.Vector; +/** + * A add-in class for IBM (r) OS/390 compilers and linkers + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public class IccProcessor { + public static void addWarningSwitch(Vector args, int level) { + switch (level) { + /* + * case 0: args.addElement("/W0"); break; + * + * case 1: args.addElement("/W1"); break; + * + * case 2: break; + * + * case 3: args.addElement("/W3"); break; + * + * case 4: args.addElement("/W4"); break; + */ + } + } + public static String getCommandFileSwitch(String cmdFile) { + StringBuffer buf = new StringBuffer("@"); + if (cmdFile.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(cmdFile); + buf.append('\"'); + } else { + buf.append(cmdFile); + } + return buf.toString(); + } + public static String getIncludeDirSwitch(String includeDir) { + return "-I" + includeDir; + } + public static String[] getOutputFileSwitch(String outPath) { + StringBuffer buf = new StringBuffer("-o "); + if (outPath.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + String[] retval = new String[]{buf.toString()}; + return retval; + } + public static boolean isCaseSensitive() { + return true; + } + private IccProcessor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/package.html b/src/main/java/net/sf/antcontrib/cpptasks/package.html new file mode 100644 index 0000000..fba9d80 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/package.html @@ -0,0 +1,27 @@ + + + + + + + +C++ and other compiled languages build support for Ant. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java new file mode 100644 index 0000000..b9bca25 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParser.java @@ -0,0 +1,67 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +import java.io.IOException; +import java.io.Reader; +/** + * An abstract base class for simple parsers + * + * @author Curt Arnold + */ +public abstract class AbstractParser { + /** + * + * + */ + protected AbstractParser() { + } + protected abstract void addFilename(String filename); + public abstract AbstractParserState getNewLineState(); + protected void parse(Reader reader) throws IOException { + char[] buf = new char[4096]; + AbstractParserState newLineState = getNewLineState(); + AbstractParserState state = newLineState; + int charsRead = -1; + do { + charsRead = reader.read(buf, 0, buf.length); + if (state == null) { + for (int i = 0; i < charsRead; i++) { + if (buf[i] == '\n') { + state = newLineState; + break; + } + } + } + if (state != null) { + for (int i = 0; i < charsRead; i++) { + state = state.consume(buf[i]); + // + // didn't match a production, skip to a new line + // + if (state == null) { + for (; i < charsRead; i++) { + if (buf[i] == '\n') { + state = newLineState; + break; + } + } + } + } + } + } while (charsRead >= 0); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java new file mode 100644 index 0000000..b3e3307 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java @@ -0,0 +1,41 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +/** + * An base class for objects that represent the state of an AbstractParser. + * + * @author CurtArnold + * @see AbstractParser + */ +public abstract class AbstractParserState { + private AbstractParser parser; + protected AbstractParserState(AbstractParser parser) { + if (parser == null) { + throw new NullPointerException("parser"); + } + this.parser = parser; + } + /** + * Consume a character + * + * @return new state, may be null to ignore the rest of the line + */ + public abstract AbstractParserState consume(char ch); + protected AbstractParser getParser() { + return parser; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java new file mode 100644 index 0000000..4b869e0 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/BranchState.java @@ -0,0 +1,46 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +public class BranchState extends AbstractParserState { + private char[] branchChars; + private AbstractParserState[] branchStates; + private AbstractParserState noMatchState; + public BranchState(AbstractParser parser, char[] branchChars, + AbstractParserState[] branchStates, AbstractParserState noMatchState) { + super(parser); + this.branchChars = (char[]) branchChars.clone(); + this.branchStates = (AbstractParserState[]) branchStates.clone(); + this.noMatchState = noMatchState; + } + public AbstractParserState consume(char ch) { + AbstractParserState state; + for (int i = 0; i < branchChars.length; i++) { + if (ch == branchChars[i]) { + state = branchStates[i]; + return state.consume(ch); + } + } + state = getNoMatchState(); + if (state != null) { + return state.consume(ch); + } + return state; + } + protected AbstractParserState getNoMatchState() { + return noMatchState; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java new file mode 100644 index 0000000..d10d889 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/CParser.java @@ -0,0 +1,78 @@ +/* + * + * Copyright 2002-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; +/** + * A parser that extracts #include statements from a Reader. + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public final class CParser extends AbstractParser implements Parser { + private final Vector includes = new Vector(); + private AbstractParserState newLineState; + /** + * + * + */ + public CParser() { + AbstractParserState quote = new FilenameState(this, new char[]{'"'}); + AbstractParserState bracket = new FilenameState(this, new char[]{'>'}); + AbstractParserState postE = new PostE(this, bracket, quote); + // + // nclude + // + AbstractParserState e = new LetterState(this, 'e', postE, null); + AbstractParserState d = new LetterState(this, 'd', e, null); + AbstractParserState u = new LetterState(this, 'u', d, null); + AbstractParserState l = new LetterState(this, 'l', u, null); + AbstractParserState c = new LetterState(this, 'c', l, null); + AbstractParserState n = new LetterState(this, 'n', c, null); + // + // mport is equivalent to nclude + // + AbstractParserState t = new LetterState(this, 't', postE, null); + AbstractParserState r = new LetterState(this, 'r', t, null); + AbstractParserState o = new LetterState(this, 'o', r, null); + AbstractParserState p = new LetterState(this, 'p', o, null); + AbstractParserState m = new LetterState(this, 'm', p, null); + // + // switch between + // + AbstractParserState n_m = new BranchState(this, new char[]{'n', 'm'}, + new AbstractParserState[]{n, m}, null); + AbstractParserState i = new WhitespaceOrLetterState(this, 'i', n_m); + newLineState = new WhitespaceOrLetterState(this, '#', i); + } + public void addFilename(String include) { + includes.addElement(include); + } + public String[] getIncludes() { + String[] retval = new String[includes.size()]; + includes.copyInto(retval); + return retval; + } + public AbstractParserState getNewLineState() { + return newLineState; + } + public void parse(Reader reader) throws IOException { + includes.setSize(0); + super.parse(reader); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java new file mode 100644 index 0000000..edcfe83 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java @@ -0,0 +1,87 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; + +/** + * This parser state checks consumed characters against a specific character + * (case insensitive). + * + * @author Curt Arnold + */ +public final class CaseInsensitiveLetterState + extends AbstractParserState { + /** + * Next state if a match is found. + */ + private final AbstractParserState nextState; + + /** + * Next state if not match is found. + */ + private final AbstractParserState noMatchState; + + /** + * Lower case version of character to match. + */ + private final char lowerLetter; + + /** + * Lower case version of character to match. + */ + private final char upperLetter; + + /** + * Constructor. + * + * @param parser + * parser + * @param matchLetter + * letter to match + * @param nextStateArg + * next state if a match on the letter + * @param noMatchStateArg + * state if no match on letter + */ + public CaseInsensitiveLetterState(final AbstractParser parser, + final char matchLetter, + final AbstractParserState nextStateArg, + final AbstractParserState noMatchStateArg) { + super(parser); + this.lowerLetter = Character.toLowerCase(matchLetter); + this.upperLetter = Character.toUpperCase(matchLetter); + this.nextState = nextStateArg; + this.noMatchState = noMatchStateArg; + } + + /** + * Consumes a character and returns the next state for the parser. + * + * @param ch + * next character + * @return the configured nextState if ch is the expected character or the + * configure noMatchState otherwise. + */ + public AbstractParserState consume(final char ch) { + if (ch == lowerLetter || ch == upperLetter) { + return nextState; + } + if (ch == '\n') { + getParser().getNewLineState(); + } + return noMatchState; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java new file mode 100644 index 0000000..f3a6193 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/FilenameState.java @@ -0,0 +1,41 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +public class FilenameState extends AbstractParserState { + private final StringBuffer buf = new StringBuffer(); + private final char[] terminators; + public FilenameState(AbstractParser parser, char[] terminators) { + super(parser); + this.terminators = (char[]) terminators.clone(); + } + public AbstractParserState consume(char ch) { + for (int i = 0; i < terminators.length; i++) { + if (ch == terminators[i]) { + getParser().addFilename(buf.toString()); + buf.setLength(0); + return null; + } + } + if (ch == '\n') { + buf.setLength(0); + return getParser().getNewLineState(); + } else { + buf.append(ch); + } + return this; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java new file mode 100644 index 0000000..d393e65 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/FortranParser.java @@ -0,0 +1,106 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; + +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; + +/** + * A parser that extracts INCLUDE statements from a Reader. + * + * @author Curt Arnold + */ +public final class FortranParser + extends AbstractParser + implements Parser { + /** + * List of included filenames. + */ + private final Vector includes = new Vector(); + + /** + * State that starts consuming content at the beginning of a line. + */ + private final AbstractParserState newLineState; + + /** + * Default constructor. + * + */ + public FortranParser() { + AbstractParserState filename = new FilenameState(this, new char[] {'\'', + '/'}); + AbstractParserState apos = new WhitespaceOrLetterState(this, '\'', + filename); + AbstractParserState blank = new LetterState(this, ' ', apos, null); + AbstractParserState e = new CaseInsensitiveLetterState(this, 'E', + blank, null); + AbstractParserState d = new CaseInsensitiveLetterState(this, 'D', e, + null); + AbstractParserState u = new CaseInsensitiveLetterState(this, 'U', d, + null); + AbstractParserState l = new CaseInsensitiveLetterState(this, 'L', u, + null); + AbstractParserState c = new CaseInsensitiveLetterState(this, 'C', l, + null); + AbstractParserState n = new CaseInsensitiveLetterState(this, 'N', c, + null); + newLineState = new WhitespaceOrCaseInsensitiveLetterState(this, 'I', n); + } + + /** + * Called by FilenameState at completion of file name production. + * + * @param include + * include file name + */ + public void addFilename(final String include) { + includes.addElement(include); + } + + /** + * Gets collection of include file names encountered in parse. + * @return include file names + */ + public String[] getIncludes() { + String[] retval = new String[includes.size()]; + includes.copyInto(retval); + return retval; + } + + /** + * Get the state for the beginning of a new line. + * @return start of line state + */ + public AbstractParserState getNewLineState() { + return newLineState; + } + + /** + * Collects all included files from the content of the reader. + * + * @param reader + * character reader containing a FORTRAN source module + * @throws IOException + * throw if I/O error during parse + */ + public void parse(final Reader reader) throws IOException { + includes.setSize(0); + super.parse(reader); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java new file mode 100644 index 0000000..fc62f9b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/LetterState.java @@ -0,0 +1,80 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; + +/** + * This parser state checks consumed characters against a specific character. + * + * @author Curt Arnold + */ +public final class LetterState + extends AbstractParserState { + /** + * Next state if a match is found. + */ + private final AbstractParserState nextState; + + /** + * Next state if not match is found. + */ + private final AbstractParserState noMatchState; + + /** + * Character to match. + */ + private final char thisLetter; + + /** + * Constructor. + * + * @param parser + * parser + * @param matchLetter + * letter to match + * @param nextStateArg + * next state if a match on the letter + * @param noMatchStateArg + * state if no match on letter + */ + public LetterState(final AbstractParser parser, + final char matchLetter, + final AbstractParserState nextStateArg, + final AbstractParserState noMatchStateArg) { + super(parser); + this.thisLetter = matchLetter; + this.nextState = nextStateArg; + this.noMatchState = noMatchStateArg; + } + + /** + * Consumes a character and returns the next state for the parser. + * + * @param ch + * next character + * @return the configured nextState if ch is the expected character or the + * configure noMatchState otherwise. + */ + public AbstractParserState consume(final char ch) { + if (ch == thisLetter) { + return nextState; + } + if (ch == '\n') { + getParser().getNewLineState(); + } + return noMatchState; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java new file mode 100644 index 0000000..bf63ae7 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/Parser.java @@ -0,0 +1,28 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +import java.io.IOException; +import java.io.Reader; +/** + * A parser that extracts #include statements from a Reader. + * + * @author Curt Arnold + */ +public interface Parser { + String[] getIncludes(); + void parse(Reader reader) throws IOException; +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java new file mode 100644 index 0000000..d599f19 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/PostE.java @@ -0,0 +1,41 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; +public class PostE extends AbstractParserState { + private AbstractParserState bracket; + private AbstractParserState quote; + public PostE(CParser parser, AbstractParserState bracket, + AbstractParserState quote) { + super(parser); + this.bracket = bracket; + this.quote = quote; + } + public AbstractParserState consume(char ch) { + switch (ch) { + case ' ' : + case '\t' : + return this; + case '<' : + return bracket; + case '"' : + return quote; + case '\n' : + return getParser().getNewLineState(); + } + return null; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java new file mode 100644 index 0000000..f7cbcea --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java @@ -0,0 +1,83 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; + +/** + * This parser state checks consumed characters against a specific character + * (case insensitive) or whitespace. + * + * @author Curt Arnold + */ +public final class WhitespaceOrCaseInsensitiveLetterState + extends + AbstractParserState { + /** + * Next state if the character is found. + */ + private final AbstractParserState nextState; + + /** + * Character to match (lower case). + */ + private final char lowerLetter; + + /** + * Character to match (upper case). + */ + private final char upperLetter; + + /** + * Constructor. + * + * @param parser + * parser + * @param matchLetter + * letter to match + * @param nextStateArg + * next state if a match on the letter + */ + public WhitespaceOrCaseInsensitiveLetterState(final AbstractParser parser, + final char matchLetter, + final AbstractParserState + nextStateArg) { + super(parser); + this.lowerLetter = Character.toLowerCase(matchLetter); + this.upperLetter = Character.toUpperCase(matchLetter); + this.nextState = nextStateArg; + } + + /** + * Consumes a character and returns the next state for the parser. + * + * @param ch + * next character + * @return the configured nextState if ch is the expected character or the + * configure noMatchState otherwise. + */ + public AbstractParserState consume(final char ch) { + if (ch == lowerLetter || ch == upperLetter) { + return nextState; + } + if (ch == ' ' || ch == '\t') { + return this; + } + if (ch == '\n') { + getParser().getNewLineState(); + } + return null; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java new file mode 100644 index 0000000..61c133d --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java @@ -0,0 +1,75 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; + +/** + * This parser state checks consumed characters against a specific character or + * whitespace. + * + * @author Curt Arnold + */ +public final class WhitespaceOrLetterState + extends AbstractParserState { + /** + * Next state if the character is found. + */ + private final AbstractParserState nextState; + + /** + * Character to match. + */ + private final char thisLetter; + + /** + * Constructor. + * + * @param parser + * parser + * @param matchLetter + * letter to match + * @param nextStateArg + * next state if a match on the letter + */ + public WhitespaceOrLetterState(final AbstractParser parser, + final char matchLetter, + final AbstractParserState nextStateArg) { + super(parser); + this.thisLetter = matchLetter; + this.nextState = nextStateArg; + } + + /** + * Consumes a character and returns the next state for the parser. + * + * @param ch + * next character @returns the configured nextState if ch is the + * expected character or the configure noMatchState otherwise. + * @return next state + */ + public AbstractParserState consume(final char ch) { + if (ch == thisLetter) { + return nextState; + } + if (ch == ' ' || ch == '\t') { + return this; + } + if (ch == '\n') { + getParser().getNewLineState(); + } + return null; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/parser/package.html b/src/main/java/net/sf/antcontrib/cpptasks/parser/package.html new file mode 100644 index 0000000..1d7aa49 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/parser/package.html @@ -0,0 +1,28 @@ + + + + + + + +Provides minimal scanners to extract dependencies, +such as include statements, from source files. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java b/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java new file mode 100644 index 0000000..f16f94e --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java @@ -0,0 +1,364 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.platforms; + +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.compiler.LinkType; + + +/** + * Platform specific behavior for Microsoft Windows. + * + * @author Curt Arnold + */ +public final class WindowsPlatform { + + /** + * Constructor. + */ + private WindowsPlatform() { + } + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + * @throws IOException if unable to write version resource + */ + public static void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) + throws IOException { + if (versionInfo == null) { + throw new NullPointerException("versionInfo"); + } + if (linkType == null) { + throw new NullPointerException("linkType"); + } + if (outputFile == null) { + throw new NullPointerException("outputFile"); + } + if (objDir == null) { + throw new NullPointerException("objDir"); + } + + /** + * Fully resolve version info + */ + VersionInfo mergedInfo = versionInfo.merge(); + + File versionResource = new File(objDir, "versioninfo.rc"); + + boolean notChanged = false; + // + // if the resource exists + // + if (versionResource.exists()) { + ByteArrayOutputStream memStream = new ByteArrayOutputStream(); + Writer writer = new BufferedWriter(new OutputStreamWriter(memStream)); + writeResource(writer, mergedInfo, outputFile, isDebug, linkType); + writer.close(); + ByteArrayInputStream proposedResource = new ByteArrayInputStream( + memStream.toByteArray()); + + InputStream existingResource = new FileInputStream(versionResource); + // + // + // + notChanged = hasSameContent(proposedResource, existingResource); + existingResource.close(); + } + + // + // if the resource file did not exist or will be changed then + // write the file + // + if (!notChanged) { + Writer writer = new BufferedWriter( + new OutputStreamWriter( + new FileOutputStream(versionResource))); + writeResource(writer, mergedInfo, outputFile, isDebug, linkType); + writer.close(); + } + if (matcher != null) { + matcher.visit(new File(versionResource.getParent()), + versionResource.getName()); + } + + } + + /** + * Compare two input streams for duplicate content + * + * Naive implementation, but should not be performance issue. + * @param stream1 stream + * @param stream2 stream + * @return true if streams are identical in content + * @throws IOException if error reading streams + */ + private static boolean hasSameContent(final InputStream stream1, + final InputStream stream2) + throws IOException { + int byte1 = -1; + int byte2 = -1; + do { + byte1 = stream1.read(); + byte2 = stream2.read(); + + } + while (byte1 == byte2 && byte1 != -1); + return (byte1 == byte2); + } + + + /** + * Parse version string into array of four short values. + * @param version String version + * @return short[] four element array + */ + public static short[] parseVersion(final String version) { + short[] values = new short[] { + 0, 0, 0, 0}; + if (version != null) { + StringBuffer buf = new StringBuffer(version); + int start = 0; + for (int i = 0; i < 4; i++) { + int end = version.indexOf('.', start); + if (end <= 0) { + end = version.length(); + for (int j = end; j > start; j--) { + String part = buf.substring(start, end); + try { + values[i] = Short.parseShort(part); + break; + } catch (NumberFormatException ex) { + values[i] = 0; + } + } + break; + } else { + String part = buf.substring(start, end); + try { + values[i] = Short.parseShort(part); + start = end + 1; + } catch (NumberFormatException ex) { + break; + } + } + } + } + return values; + } + + /** + * Converts parsed version information into a string representation. + * + * @param buf StringBuffer string buffer to receive version number + * @param version short[] four-element array + */ + private static void encodeVersion(final StringBuffer buf, + final short[] version) { + for (int i = 0; i < 3; i++) { + buf.append(Short.toString(version[i])); + buf.append(','); + } + buf.append(Short.toString(version[3])); + } + + /** + * Writes windows resource. + * @param writer writer, may not be nul + * @param versionInfo version information + * @param outputFile executable file + * @param isDebug true if debug + * @param linkType link type + * @throws IOException if error writing resource file + */ + public static void writeResource(final Writer writer, + final VersionInfo versionInfo, + final File outputFile, + final boolean isDebug, + final LinkType linkType) throws IOException { + + //writer.write("#include \"windows.h\"\n"); + + writer.write("VS_VERSION_INFO VERSIONINFO\n"); + StringBuffer buf = new StringBuffer("FILEVERSION "); + encodeVersion(buf, parseVersion(versionInfo.getFileversion())); + buf.append("\nPRODUCTVERSION "); + encodeVersion(buf, parseVersion(versionInfo.getProductversion())); + buf.append("\n"); + writer.write(buf.toString()); + buf.setLength(0); + buf.append("FILEFLAGSMASK 0x1L /* VS_FF_DEBUG */"); + Boolean patched = versionInfo.getPatched(); + Boolean prerelease = versionInfo.getPrerelease(); + if (patched != null) { + buf.append(" | 0x4L /* VS_FF_PATCHED */"); + } + if (prerelease != null) { + buf.append(" | 0x2L /* VS_FF_PRERELEASE */"); + } + if (versionInfo.getPrivatebuild() != null) { + buf.append(" | 0x8L /* VS_FF_PRIVATEBUILD */"); + } + if (versionInfo.getSpecialbuild() != null) { + buf.append(" | 0x20L /* VS_FF_SPECIALBUILD */"); + } + buf.append('\n'); + writer.write(buf.toString()); + buf.setLength(0); + buf.append("FILEFLAGS "); + + if (isDebug) { + buf.append("0x1L /* VS_FF_DEBUG */ | "); + } + if (Boolean.TRUE.equals(patched)) { + buf.append("0x4L /* VS_FF_PATCHED */ | "); + } + if (Boolean.TRUE.equals(prerelease)) { + buf.append("0x2L /* VS_FF_PRERELEASE */ | "); + } + if (Boolean.TRUE.equals(versionInfo.getPrivatebuild())) { + buf.append("0x8L /* VS_FF_PRIVATEBUILD */ | "); + } + if (Boolean.TRUE.equals(versionInfo.getSpecialbuild())) { + buf.append("0x20L /* VS_FF_SPECIALBUILD */ | "); + } + if (buf.length() > 10) { + buf.setLength(buf.length() - 3); + buf.append('\n'); + } else { + buf.append("0\n"); + } + writer.write(buf.toString()); + buf.setLength(0); + + writer.write("FILEOS 0x40004 /* VOS_NT_WINDOWS32 */\nFILETYPE "); + if (linkType.isExecutable()) { + writer.write("0x1L /* VFT_APP */\n"); + } else { + if (linkType.isSharedLibrary()) { + writer.write("0x2L /* VFT_DLL */\n"); + } else if (linkType.isStaticLibrary()) { + writer.write("0x7L /* VFT_STATIC_LIB */\n"); + } else { + writer.write("0x0L /* VFT_UNKNOWN */\n"); + } + } + writer.write("FILESUBTYPE 0x0L\n"); + writer.write("BEGIN\n"); + writer.write("BLOCK \"StringFileInfo\"\n"); + writer.write(" BEGIN\n#ifdef UNICODE\nBLOCK \"040904B0\"\n"); + writer.write("#else\nBLOCK \"040904E4\"\n#endif\n"); + writer.write("BEGIN\n"); + if (versionInfo.getFilecomments() != null) { + writer.write("VALUE \"Comments\", \""); + writer.write(versionInfo.getFilecomments()); + writer.write("\\0\"\n"); + } + if (versionInfo.getCompanyname() != null) { + writer.write("VALUE \"CompanyName\", \""); + writer.write(versionInfo.getCompanyname()); + writer.write("\\0\"\n"); + } + if (versionInfo.getFiledescription() != null) { + writer.write("VALUE \"FileDescription\", \""); + writer.write(versionInfo.getFiledescription()); + writer.write("\\0\"\n"); + } + if (versionInfo.getFileversion() != null) { + writer.write("VALUE \"FileVersion\", \""); + writer.write(versionInfo.getFileversion()); + writer.write("\\0\"\n"); + } + String baseName = CUtil.getBasename(outputFile); + String internalName = versionInfo.getInternalname(); + if (internalName == null) { + internalName = baseName; + } + writer.write("VALUE \"InternalName\", \""); + writer.write(internalName); + writer.write("\\0\"\n"); + if (versionInfo.getLegalcopyright() != null) { + writer.write("VALUE \"LegalCopyright\", \""); + writer.write(versionInfo.getLegalcopyright()); + writer.write("\\0\"\n"); + } + if (versionInfo.getLegaltrademarks() != null) { + writer.write("VALUE \"LegalTrademarks\", \""); + writer.write(versionInfo.getLegaltrademarks()); + writer.write("\\0\"\n"); + } + writer.write("VALUE \"OriginalFilename\", \""); + writer.write(baseName); + writer.write("\\0\"\n"); + if (versionInfo.getPrivatebuild() != null) { + writer.write("VALUE \"PrivateBuild\", \""); + writer.write(versionInfo.getPrivatebuild()); + writer.write("\\0\"\n"); + } + if (versionInfo.getProductname() != null) { + writer.write("VALUE \"ProductName\", \""); + writer.write(versionInfo.getProductname()); + writer.write("\\0\"\n"); + } + if (versionInfo.getProductversion() != null) { + writer.write("VALUE \"ProductVersion\", \""); + writer.write(versionInfo.getProductversion()); + writer.write("\\0\"\n"); + } + if (versionInfo.getSpecialbuild() != null) { + writer.write("VALUE \"SpecialBuild\", \""); + writer.write(versionInfo.getSpecialbuild()); + writer.write("\\0\"\n"); + } + writer.write("END\n"); + writer.write("END\n"); + + writer.write("BLOCK \"VarFileInfo\"\n"); + writer.write("BEGIN\n#ifdef UNICODE\n"); + writer.write("VALUE \"Translation\", 0x409, 1200\n"); + writer.write("#else\n"); + writer.write("VALUE \"Translation\", 0x409, 1252\n"); + writer.write("#endif\n"); + writer.write("END\n"); + writer.write("END\n"); + } + +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html b/src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html new file mode 100644 index 0000000..e054c41 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/platforms/package.html @@ -0,0 +1,27 @@ + + + + + + + +Platform specific utilities. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java new file mode 100644 index 0000000..4ac8ac1 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java @@ -0,0 +1,108 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.sun; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for the Sun C89 C++ Compiler + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public class C89CCompiler extends CommandLineCCompiler { + private static final AbstractCompiler instance = new C89CCompiler(false, + null); + public static AbstractCompiler getInstance() { + return instance; + } + private C89CCompiler(boolean newEnvironment, Environment env) { + super("c89", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++"}, + new String[]{".h", ".hpp"}, ".o", false, null, newEnvironment, + env); + } + protected void addImpliedArgs( + final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + // Specifies that only compilations and assemblies be done. + args.addElement("-c"); + /* + * if (exceptions) { args.addElement("/GX"); } + */ + if (debug) { + args.addElement("-g"); + args.addElement("-D_DEBUG"); + /* + * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) { + * args.addElement("/MTd"); } else { args.addElement("/MDd"); + * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); } + */ + } else { + args.addElement("-DNDEBUG"); + /* + * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) { + * args.addElement("/MT"); } else { args.addElement("/MD"); + * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); } + */ + } + } + protected void addWarningSwitch(Vector args, int level) { + C89Processor.addWarningSwitch(args, level); + } + public Processor changeEnvironment(boolean newEnvironment, Environment env) { + if (newEnvironment || env != null) { + return new C89CCompiler(newEnvironment, env); + } + return this; + } + protected void getDefineSwitch(StringBuffer buf, String define, String value) { + C89Processor.getDefineSwitch(buf, define, value); + } + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("INCLUDE", ":"); + } + protected String getIncludeDirSwitch(String includeDir) { + return C89Processor.getIncludeDirSwitch(includeDir); + } + public Linker getLinker(LinkType type) { + return C89Linker.getInstance().getLinker(type); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + /* Only compile one file at time for now */ + protected int getMaximumInputFilesPerCommand() { + return 1; + } + protected void getUndefineSwitch(StringBuffer buf, String define) { + C89Processor.getUndefineSwitch(buf, define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java new file mode 100644 index 0000000..6c41c89 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Linker.java @@ -0,0 +1,132 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.sun; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +import net.sf.antcontrib.cpptasks.VersionInfo; + +/** + * Adapter for the Sun C89 Linker + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public final class C89Linker extends CommandLineLinker { + private static final C89Linker dllLinker = new C89Linker("lib", ".so"); + private static final C89Linker instance = new C89Linker("", ""); + public static C89Linker getInstance() { + return instance; + } + private String outputPrefix; + private C89Linker(String outputPrefix, String outputSuffix) { + super("ld", "/bogus", new String[]{".o", ".a", ".lib", ".x"}, + new String[]{}, outputSuffix, false, null); + this.outputPrefix = outputPrefix; + } + protected void addBase(long base, Vector args) { + } + protected void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (linkType.isSharedLibrary()) { + args.addElement("-G"); + } + } + protected void addIncremental(boolean incremental, Vector args) { + } + public String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + super.addLibrarySets(task, libsets, preargs, midargs, endargs); + StringBuffer buf = new StringBuffer("-l"); + for (int i = 0; i < libsets.length; i++) { + LibrarySet set = libsets[i]; + File libdir = set.getDir(null); + String[] libs = set.getLibs(); + if (libdir != null) { + endargs.addElement("-L"); + endargs.addElement(libdir.getAbsolutePath()); + } + for (int j = 0; j < libs.length; j++) { + // + // reset the buffer to just "-l" + // + buf.setLength(2); + // + // add the library name + buf.append(libs[j]); + // + // add the argument to the list + endargs.addElement(buf.toString()); + } + } + return null; + } + protected void addMap(boolean map, Vector args) { + } + protected void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + public String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + public File[] getLibraryPath() { + return CUtil.getPathFromEnvironment("LIB", ";"); + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return C89Processor.getLibraryPatterns(libnames, libType); + } + public Linker getLinker(LinkType linkType) { + if (linkType.isSharedLibrary()) { + return dllLinker; + } + /* + * if(linkType.isStaticLibrary()) { return + * OS390Librarian.getInstance(); } + */ + return instance; + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + String[] baseNames = super.getOutputFileNames(baseName, versionInfo); + if (outputPrefix.length() > 0) { + for(int i = 0; i < baseNames.length; i++) { + baseNames[i] = outputPrefix + baseNames[i]; + } + } + return baseNames; + } + public String[] getOutputFileSwitch(String outputFile) { + return new String[]{"-o", outputFile}; + } + public boolean isCaseSensitive() { + return C89Processor.isCaseSensitive(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java new file mode 100644 index 0000000..343293a --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/C89Processor.java @@ -0,0 +1,116 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.sun; +import java.util.Vector; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * A add-in class for Sun C89 compilers and linkers + * + * @author Hiram Chirino (cojonudo14@hotmail.com) + */ +public class C89Processor { + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + public static void addWarningSwitch(Vector args, int level) { + switch (level) { + /* + * case 0: args.addElement("/W0"); break; + * + * case 1: args.addElement("/W1"); break; + * + * case 2: break; + * + * case 3: args.addElement("/W3"); break; + * + * case 4: args.addElement("/W4"); break; + */ + } + } + public static String getCommandFileSwitch(String cmdFile) { + StringBuffer buf = new StringBuffer("@"); + if (cmdFile.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(cmdFile); + buf.append('\"'); + } else { + buf.append(cmdFile); + } + return buf.toString(); + } + public static void getDefineSwitch(StringBuffer buf, String define, + String value) { + buf.setLength(0); + buf.append("-D"); + buf.append(define); + if (value != null && value.length() > 0) { + buf.append('='); + buf.append(value); + } + } + public static String getIncludeDirSwitch(String includeDir) { + return "-I" + includeDir; + } + public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + int patternCount = libnames.length*2; + if (libType != null) { + patternCount = libnames.length; + } + String[] patterns = new String[patternCount]; + int offset = 0; + if (libType == null || "static".equals(libType.getValue())) { + offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + } + if (libType == null || !"static".equals(libType.getValue())) { + offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns, + offset); + } + return patterns; + } + public static String[] getOutputFileSwitch(String outPath) { + StringBuffer buf = new StringBuffer("-o "); + if (outPath.indexOf(' ') >= 0) { + buf.append('\"'); + buf.append(outPath); + buf.append('\"'); + } else { + buf.append(outPath); + } + String[] retval = new String[]{buf.toString()}; + return retval; + } + public static void getUndefineSwitch(StringBuffer buf, String define) { + buf.setLength(0); + buf.append("-U"); + buf.append(define); + } + public static boolean isCaseSensitive() { + return true; + } + private C89Processor() { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java new file mode 100644 index 0000000..9422e49 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java @@ -0,0 +1,130 @@ +/* + * + * Copyright 2001-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.sun; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler; +import net.sf.antcontrib.cpptasks.OptimizationEnum; +/** + * Adapter for the Sun (r) Forte (tm) C++ compiler + * + * @author Curt Arnold + */ +public final class ForteCCCompiler extends GccCompatibleCCompiler { + private final static String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + private final static String[] sourceExtensions = new String[]{".c", ".cc", + ".cxx", ".cpp", ".c++", ".i", ".s"}; + + private static final ForteCCCompiler instance = new ForteCCCompiler("CC", + sourceExtensions, headerExtensions); + /** + * Gets singleton instance of this class + */ + public static ForteCCCompiler getInstance() { + return instance; + } + private String identifier; + private File[] includePath; + /** + * Private constructor. Use ForteCCCompiler.getInstance() to get singleton + * instance of this class. + */ + private ForteCCCompiler(String command, String[] sourceExtensions, + String[] headerExtensions) { + super(command, "-V", sourceExtensions, headerExtensions, false, null, + false, null); + } + public void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + args.addElement("-c"); + if (debug) { + args.addElement("-g"); + } + if (optimization != null) { + if (optimization.isSpeed()) { + args.addElement("-xO2"); + } + } + if (rtti != null) { + if (rtti.booleanValue()) { + args.addElement("-features=rtti"); + } else { + args.addElement("-features=no%rtti"); + } + } + if (multithreaded) { + args.addElement("-mt"); + } + if (linkType.isSharedLibrary()) { + args.addElement("-KPIC"); + } + + } + public void addWarningSwitch(Vector args, int level) { + switch (level) { + case 0 : + args.addElement("-w"); + break; + case 1 : + case 2 : + break; + case 3 : + args.addElement("+w"); + break; + case 4 : + args.addElement("+w2"); + break; + case 5 : + args.addElement("+w2"); + args.addElement("-xwe"); + } + } + public File[] getEnvironmentIncludePath() { + if (includePath == null) { + File ccLoc = CUtil.getExecutableLocation("CC"); + if (ccLoc != null) { + File compilerIncludeDir = new File( + new File(ccLoc, "../include").getAbsolutePath()); + if (compilerIncludeDir.exists()) { + includePath = new File[2]; + includePath[0] = compilerIncludeDir; + } + } + if (includePath == null) { + includePath = new File[1]; + } + includePath[includePath.length - 1] = new File("/usr/include"); + } + return includePath; + } + public Linker getLinker(LinkType linkType) { + return ForteCCLinker.getInstance().getLinker(linkType); + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java new file mode 100644 index 0000000..47d2155 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java @@ -0,0 +1,100 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.sun; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker; +/** + * Adapter for Sun (r) Forte(tm) C++ Linker + * + * @author Curt Arnold + */ +public final class ForteCCLinker extends AbstractLdLinker { + private static final String[] discardFiles = new String[]{".dll", ".so", + ".sl"}; + private static final String[] objFiles = new String[]{".o", ".a", ".lib"}; + private static final ForteCCLinker arLinker = new ForteCCLinker("CC", + objFiles, discardFiles, "lib", ".a"); + private static final ForteCCLinker dllLinker = new ForteCCLinker("CC", + objFiles, discardFiles, "lib", ".so"); + private static final ForteCCLinker instance = new ForteCCLinker("CC", + objFiles, discardFiles, "", ""); + public static ForteCCLinker getInstance() { + return instance; + } + private File[] libDirs; + private ForteCCLinker(String command, String[] extensions, + String[] ignoredExtensions, String outputPrefix, String outputSuffix) { + super(command, "-V", extensions, ignoredExtensions, outputPrefix, + outputSuffix, false, null); + } + public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (debug) { + args.addElement("-g"); + } + if (linkType.isStaticRuntime()) { + args.addElement("-static"); + } + if (linkType.isSharedLibrary()) { + args.addElement("-G"); + } + if (linkType.isStaticLibrary()) { + args.addElement("-xar"); + } + } + public void addIncremental(boolean incremental, Vector args) { + /* + * if (incremental) { args.addElement("-xidlon"); } else { + * args.addElement("-xidloff"); } + */ + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + if (libDirs == null) { + File CCloc = CUtil.getExecutableLocation("CC"); + if (CCloc != null) { + File compilerLib = new File(new File(CCloc, "../lib") + .getAbsolutePath()); + if (compilerLib.exists()) { + libDirs = new File[2]; + libDirs[0] = compilerLib; + } + } + if (libDirs == null) { + libDirs = new File[1]; + } + } + libDirs[libDirs.length - 1] = new File("/usr/lib"); + return libDirs; + } + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + return arLinker; + } + if (type.isSharedLibrary()) { + return dllLinker; + } + return instance; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java new file mode 100644 index 0000000..c844ac4 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java @@ -0,0 +1,191 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ti; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.OptimizationEnum; + + +import org.apache.tools.ant.types.Environment; +/** + * Adapter for TI DSP compilers with cl** commands + * + * @author CurtA + */ +public class ClxxCCompiler extends CommandLineCCompiler { + /** + * Header file extensions + */ + private static final String[] headerExtensions = new String[]{".h", ".hpp", + ".inl"}; + /** + * Source file extensions + */ + private static final String[] sourceExtensions = new String[]{".c", ".cc", + ".cpp", ".cxx", ".c++"}; + /** + * Singleton for TMS320C55x + */ + private static final ClxxCCompiler cl55 = new ClxxCCompiler("cl55", false, + null); + /** + * Singleton for TMS320C6000 + */ + private static final ClxxCCompiler cl6x = new ClxxCCompiler("cl6x", false, + null); + public static ClxxCCompiler getCl55Instance() { + return cl55; + } + public static ClxxCCompiler getCl6xInstance() { + return cl6x; + } + /** + * Private constructor + * + * @param command + * executable name + * @param newEnvironment + * Change environment + * @param env + * New environment + */ + private ClxxCCompiler(String command, boolean newEnvironment, + Environment env) { + super(command, "-h", sourceExtensions, headerExtensions, ".o", false, + null, newEnvironment, env); + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addImpliedArgs(java.util.Vector, + * boolean, boolean, boolean, + * net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + protected void addImpliedArgs( + final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + if (debug) { + args.addElement("-gw"); + } + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addWarningSwitch(java.util.Vector, + * int) + */ + protected void addWarningSwitch(Vector args, int warnings) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getDefineSwitch(java.lang.StringBuffer, + * java.lang.String, java.lang.String) + */ + protected void getDefineSwitch(StringBuffer buffer, String define, + String value) { + buffer.append("-d"); + buffer.append(define); + if (value != null) { + buffer.append('='); + buffer.append(value); + } + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getEnvironmentIncludePath() + */ + protected File[] getEnvironmentIncludePath() { + File[] c_dir = CUtil.getPathFromEnvironment("C_DIR", ";"); + File[] cx_dir = CUtil.getPathFromEnvironment("C6X_C_DIR", ";"); + if (c_dir.length == 0) { + return cx_dir; + } + if (cx_dir.length == 0) { + return c_dir; + } + File[] combo = new File[c_dir.length + cx_dir.length]; + for (int i = 0; i < cx_dir.length; i++) { + combo[i] = cx_dir[i]; + } + for (int i = 0; i < c_dir.length; i++) { + combo[i + cx_dir.length] = c_dir[i]; + } + return combo; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getIncludeDirSwitch(java.lang.String) + */ + protected String getIncludeDirSwitch(String source) { + return "-I" + source; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + public Linker getLinker(LinkType type) { + if (type.isStaticLibrary()) { + if (this == cl6x) { + return ClxxLibrarian.getCl6xInstance(); + } + return ClxxLibrarian.getCl55Instance(); + } + if (type.isSharedLibrary()) { + if (this == cl6x) { + return ClxxLinker.getCl6xDllInstance(); + } + return ClxxLinker.getCl55DllInstance(); + } + if (this == cl6x) { + return ClxxLinker.getCl6xInstance(); + } + return ClxxLinker.getCl55Instance(); + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getMaximumCommandLength() + */ + public int getMaximumCommandLength() { + return 1024; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getUndefineSwitch(java.lang.StringBuffer, + * java.lang.String) + */ + protected void getUndefineSwitch(StringBuffer buffer, String define) { + buffer.append("-u"); + buffer.append(define); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java new file mode 100644 index 0000000..c48815a --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java @@ -0,0 +1,162 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ti; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * + * Adapter for TI DSP librarian + * * + * @author CurtA + */ +public class ClxxLibrarian extends CommandLineLinker { + private static final ClxxLibrarian cl55Instance = new ClxxLibrarian("ar55"); + private static final ClxxLibrarian cl6xInstance = new ClxxLibrarian("ar6x"); + public static final ClxxLibrarian getCl55Instance() { + return cl55Instance; + } + public static final ClxxLibrarian getCl6xInstance() { + return cl6xInstance; + } + private ClxxLibrarian(String command) { + super(command, null, new String[]{".o"}, new String[0], ".lib", false, + null); + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long, + * java.util.Vector) + */ + protected void addBase(long base, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean, + * java.util.Vector) + */ + protected void addFixed(Boolean fixed, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean, + * net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector) + */ + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean, + * java.util.Vector) + */ + protected void addIncremental(boolean incremental, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean, + * java.util.Vector) + */ + protected void addMap(boolean map, Vector args) { + // TODO Auto-generated method stub + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int, + * java.util.Vector) + */ + protected void addStack(int stack, Vector args) { + // TODO Auto-generated method stub + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String) + */ + protected String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath() + */ + public File[] getLibraryPath() { + return new File[0]; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[]) + */ + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return new String[0]; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + public Linker getLinker(LinkType linkType) { + return null; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength() + */ + protected int getMaximumCommandLength() { + return 1024; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String) + */ + protected String[] getOutputFileSwitch(String outputFile) { + return new String[]{"-o", outputFile}; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive() + */ + public boolean isCaseSensitive() { + // TODO Auto-generated method stub + return false; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java new file mode 100644 index 0000000..bb644a4 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java @@ -0,0 +1,181 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ti; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Adapter for TI DSP linkers + * * + * @author CurtA + * + */ +public class ClxxLinker extends CommandLineLinker { + private static final ClxxLinker cl55DllInstance = new ClxxLinker("lnk55", + ".dll"); + private static final ClxxLinker cl55Instance = new ClxxLinker("lnk55", + ".exe"); + private static final ClxxLinker cl6xDllInstance = new ClxxLinker("lnk6x", + ".dll"); + private static final ClxxLinker cl6xInstance = new ClxxLinker("lnk6x", + ".exe"); + public static ClxxLinker getCl55DllInstance() { + return cl55DllInstance; + } + public static ClxxLinker getCl55Instance() { + return cl55Instance; + } + public static ClxxLinker getCl6xDllInstance() { + return cl6xDllInstance; + } + public static ClxxLinker getCl6xInstance() { + return cl6xInstance; + } + private ClxxLinker(String command, String outputSuffix) { + super(command, "-h", new String[]{".o", ".lib", ".res"}, new String[]{ + ".map", ".pdb", ".lnk"}, outputSuffix, false, null); + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long, + * java.util.Vector) + */ + protected void addBase(long base, Vector args) { + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean, + * java.util.Vector) + */ + protected void addFixed(Boolean fixed, Vector args) { + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean, + * net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector) + */ + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (linkType.isSharedLibrary()) { + args.addElement("-abs"); + } + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean, + * java.util.Vector) + */ + protected void addIncremental(boolean incremental, Vector args) { + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean, + * java.util.Vector) + */ + protected void addMap(boolean map, Vector args) { + if (map) { + args.addElement("-m"); + } + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int, + * java.util.Vector) + */ + protected void addStack(int stack, Vector args) { + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + } + + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String) + */ + protected String getCommandFileSwitch(String commandFile) { + return "@" + commandFile; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath() + */ + public File[] getLibraryPath() { + return new File[0]; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[]) + */ + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + // + // TODO: Looks bogus, should be .a or .so's not .o's + // + String[] libpats = new String[libnames.length]; + for (int i = 0; i < libnames.length; i++) { + libpats[i] = libnames[i] + ".o"; + } + return libpats; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType) + */ + public Linker getLinker(LinkType linkType) { + return this; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength() + */ + protected int getMaximumCommandLength() { + return 1024; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String) + */ + protected String[] getOutputFileSwitch(String outputFile) { + return new String[]{"-o", outputFile}; + } + /* + * (non-Javadoc) + * + * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive() + */ + public boolean isCaseSensitive() { + // TODO Auto-generated method stub + return false; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java new file mode 100644 index 0000000..25651da --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectCompiler.java @@ -0,0 +1,280 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.trolltech; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.FileReader; +import java.io.Reader; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.OptimizationEnum; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.gcc.LdLinker; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.types.Environment; + +/** + * Adapter for the Trolltech Qt MOC Compiler. + * + * @author Curt Arnold + */ +public final class MetaObjectCompiler + extends CommandLineCompiler { + /** + * Singleton instance. + */ + private static final MetaObjectCompiler INSTANCE = new MetaObjectCompiler( + false, null); + + /** + * Gets singleton instance of compiler. + * @return MetaObjectCompiler singleton instance + */ + public static MetaObjectCompiler getInstance() { + return INSTANCE; + } + + /** + * Constructor. + * @param newEnvironment boolean establish an new environment. + * @param env Environment environment. + */ + private MetaObjectCompiler(final boolean newEnvironment, + final Environment env) { + super("moc", "-version", new String[] {".h", ".cpp"} + , new String[0], ".moc", false, null, newEnvironment, env); + } + + /** + * Add arguments for debug, etc. + * @param args Vector command argument list + * @param debug boolean build for debug if true + * @param multithreaded boolean build for multithreading if true + * @param exceptions boolean enable exceptions if true + * @param linkType LinkType output and runtime type + * @param rtti Boolean enable run-time type identification if true + * @param optimization OptimizationEnum optimization + */ + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + } + + /** + * Add arguments for specified warning level. + * @param args Vector command line arguments + * @param level int warning level value + */ + protected void addWarningSwitch(final Vector args, final int level) { + } + + /** + * Change enviroment (deprecated). + * @param newEnvironment boolean use new environment. + * @param env Environment environment + * @return Processor modified processor + */ + public Processor changeEnvironment(final boolean newEnvironment, + final Environment env) { + return this; + } + + /** + * Gets a parser to scan source file for dependencies. + * @param source source file + * @return parser + */ + protected Parser createParser(final File source) { + return new CParser(); + } + + /** + * Gets number of command line arguments per input file. + * @return int number of command line arguments per input file. + */ + protected int getArgumentCountPerInputFile() { + return 3; + } + + /** + * Returns the bid of the processor for the file. + * + * @param inputFile + * filename of input file + * @return bid for the file, 0 indicates no interest, 1 indicates that the + * processor recognizes the file but doesn't process it (header + * files, for example), 100 indicates strong interest + */ + public int bid(final String inputFile) { + // + // get base bid + int baseBid = super.bid(inputFile); + // + // if the base bid was non-zero (.h or .cpp extension) + // + if (baseBid > 0) { + // + // scan the file for Q_OBJECT + // skip file if not present + // + try { + Reader reader = new BufferedReader(new FileReader(inputFile)); + boolean hasQObject = MetaObjectParser.hasQObject(reader); + reader.close(); + if (hasQObject) { + return baseBid; + } + } catch (IOException ex) { + return 0; + } + } + return 0; + } + + /** + * Gets output file names. + * @param inputFile String input file name + * @param versionInfo version info, not used by this compiler. + * @return String[] output file names + */ + public String[] getOutputFileNames(final String inputFile, + final VersionInfo versionInfo) { + if (inputFile.endsWith(".cpp")) { + return super.getOutputFileNames(inputFile, versionInfo); + } + // + // if a recognized input file + // + String baseName = getBaseOutputName(inputFile); + return new String[] { + "moc_" + baseName + ".cpp"}; + } + + /** + * Gets input file arguments. + * @param outputDir File output directory + * @param filename String input file name. + * @param index int argument index, + * 0 to getNumberOfArgumentsPerInputFile() -1 + * @return String input file argument + */ + protected String getInputFileArgument(final File outputDir, + final String filename, + final int index) { + switch (index) { + case 0: + return "-o"; + case 1: + String outputFileName = getOutputFileNames(filename, null)[0]; + return new File(outputDir, outputFileName) + .toString(); + + case 2: + return filename; + + default: + return null; + } + } + + /** + * Gets maximum length of command line. + * @return int maximum length of command line + */ + public int getMaximumCommandLength() { + return 1024; + } + + /** + * Gets maximum number of input files processed per command. + * @return int maximum number of input files processed per command. + */ + protected int getMaximumInputFilesPerCommand() { + return 1; + } + + /** + * Gets include directory switch. + * @param includeDir String include directory + * @return String command switch to add specified directory to search path + */ + protected String getIncludeDirSwitch(final String includeDir) { + return ""; + } + + /** + * Gets switch to define preprocessor macro. + * @param buffer StringBuffer command line argument + * @param define String macro name + * @param value String macro value, may be null. + */ + protected void getDefineSwitch(final StringBuffer buffer, + final String define, + final String value) { + } + + /** + * Gets switch to undefine preprocessor macro. + * @param buffer StringBuffer command line argument + * @param define String macro name + */ + protected void getUndefineSwitch(final StringBuffer buffer, + final String define) { + } + + /** + * Gets standard include paths. + * @return File[] standard include paths + */ + protected File[] getEnvironmentIncludePath() { + return new File[0]; + } + + /** + * Gets linker associated with this type. + * @param type LinkType linker, returns ld. + * @return Linker + */ + public Linker getLinker(final LinkType type) { + return LdLinker.getInstance(); + } + + /** + * Get total command line length due to the input file. + * @param outputDir File output directory + * @param inputFile String input file + * @return int characters added to command line for the input file. + */ + protected int getTotalArgumentLengthForInputFile(final File outputDir, + final String inputFile) { + String arg1 = getInputFileArgument(outputDir, inputFile, 0); + String arg2 = getInputFileArgument(outputDir, inputFile, 1); + return arg1.length() + arg2.length() + 3; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java new file mode 100644 index 0000000..e75a116 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/MetaObjectParser.java @@ -0,0 +1,148 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.trolltech; + +import java.io.IOException; +import java.io.Reader; + +import net.sf.antcontrib.cpptasks.parser.AbstractParser; +import net.sf.antcontrib.cpptasks.parser.AbstractParserState; +import net.sf.antcontrib.cpptasks.parser.LetterState; +import net.sf.antcontrib.cpptasks.parser.WhitespaceOrLetterState; + +/** + * Scans a source file for Q_OBJECT. + * + * @author Curt Arnold + */ +public final class MetaObjectParser + extends AbstractParser { + /** + * Parser state that matches file T character. + */ + private static final class FinalTState + extends AbstractParserState { + /** + * Parser. + */ + private final MetaObjectParser mocParser; + + /** + * Constructor. + * @param parser MetaObjectParser parser + */ + public FinalTState(final MetaObjectParser parser) { + super(parser); + this.mocParser = parser; + } + + /** + * Consumes a character and returns the next state for the parser. + * + * @param ch + * next character + * @return the configured nextState if ch is the expected character or the + * configure noMatchState otherwise. + */ + public AbstractParserState consume(final char ch) { + if (ch == 'T') { + mocParser.setQObject(true); + return null; + } + if (ch == '\n') { + getParser().getNewLineState(); + } + return null; + } + } + + /** + * Determines if source file contains Q_OBJECT. + * @param reader Reader source reader + * @throws IOException if unable to read source file + * @return boolean true if source contains Q_OBJECT + */ + public static boolean hasQObject(final Reader reader) throws IOException { + MetaObjectParser parser = new MetaObjectParser(); + parser.parse(reader); + return parser.hasQObject; + + } + + /** + * Has Q_OBJECT been encountered. + */ + private boolean hasQObject = false; + + /** + * Parser state for start of new line. + */ + private AbstractParserState newLineState; + + /** + * Constructor. + * + */ + private MetaObjectParser() { + // + // search for Q_OBJECT + // + AbstractParserState t = new FinalTState(this); + AbstractParserState c = new LetterState(this, 'C', t, null); + AbstractParserState e = new LetterState(this, 'E', c, null); + AbstractParserState j = new LetterState(this, 'J', e, null); + AbstractParserState b = new LetterState(this, 'B', j, null); + AbstractParserState o = new LetterState(this, 'O', b, null); + AbstractParserState underline = new LetterState(this, '_', o, null); + newLineState = new WhitespaceOrLetterState(this, 'Q', underline); + } + + /** + * Adds a filename to the list of included files. + * + * @param filename filename to be added + */ + protected void addFilename(final String filename) { + + } + + /** + * Gets new line state. + * @return AbstractParserState new line state. + */ + public AbstractParserState getNewLineState() { + return newLineState; + } + + /** + * Parse input file. + * @param reader Reader source file + * @throws IOException if error reading source file + */ + public void parse(final Reader reader) throws IOException { + hasQObject = false; + super.parse(reader); + } + + /** + * Called FinalTState to set that Q_OBJECT was found. + * @param value boolean new value for hasQObject + */ + public void setQObject(final boolean value) { + this.hasQObject = value; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java new file mode 100644 index 0000000..cc4cf3b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceCompiler.java @@ -0,0 +1,347 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.trolltech; + +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.OptimizationEnum; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.compiler.Processor; +import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor; +import net.sf.antcontrib.cpptasks.gcc.LdLinker; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Environment; + +/** + * Adapter for the Trolltech Qt UIC Compiler. + * + * @author Curt Arnold + */ +public final class UserInterfaceCompiler + extends CommandLineCompiler { + /** + * Singleton instance. + */ + private static final UserInterfaceCompiler INSTANCE = new + UserInterfaceCompiler( + false, null); + + /** + * Gets singleton instance of compiler. + * @return MetaObjectCompiler singleton instance + */ + public static UserInterfaceCompiler getInstance() { + return INSTANCE; + } + + /** + * Constructor. + * @param newEnvironment boolean establish an new environment. + * @param env Environment environment. + */ + private UserInterfaceCompiler(final boolean newEnvironment, + final Environment env) { + super("uic", "-version", new String[] {".ui"} + , new String[0], ".h", false, null, newEnvironment, env); + } + + /** + * Add arguments for debug, etc. + * @param args Vector command argument list + * @param debug boolean build for debug if true + * @param multithreaded boolean build for multithreading if true + * @param exceptions boolean enable exceptions if true + * @param linkType LinkType output and runtime type + * @param rtti Boolean enable run-time type identification if true + * @param optimization OptimizationEnum optimization + */ + protected void addImpliedArgs(final Vector args, + final boolean debug, + final boolean multithreaded, + final boolean exceptions, + final LinkType linkType, + final Boolean rtti, + final OptimizationEnum optimization) { + } + + /** + * Add arguments for specified warning level. + * @param args Vector command line arguments + * @param level int warning level value + */ + protected void addWarningSwitch(final Vector args, final int level) { + } + + /** + * Change enviroment (deprecated). + * @param newEnvironment boolean use new environment. + * @param env Environment environment + * @return Processor modified processor + */ + public Processor changeEnvironment(final boolean newEnvironment, + final Environment env) { + return this; + } + + /** + * The include parser for C will work just fine, but we didn't want to + * inherit from CommandLineCCompiler. + * @param source source file to be parsed + * @return parser + */ + protected Parser createParser(final File source) { + return new UserInterfaceParser(); + } + + /** + * Gets number of command line arguments per input file. + * @return int number of command line arguments per input file. + */ + protected int getArgumentCountPerInputFile() { + return 3; + } + + /** + * Gets output file names. + * @param inputFile String input file name + * @param versionInfo version info, not used by this compiler. + * @return String[] output file names + */ + public String[] getOutputFileNames(final String inputFile, + final VersionInfo versionInfo) { + // + // if a recognized input file + // + String baseName = getBaseOutputName(inputFile); + return new String[] { + baseName + ".h", + baseName + ".cpp", + "moc_" + baseName + ".cpp"}; + } + + /** + * Gets input file arguments. + * @param outputDir File output directory + * @param filename String input file name. + * @param index int argument index, + * 0 to getNumberOfArgumentsPerInputFile() -1 + * @return String input file argument + */ + protected String getInputFileArgument(final File outputDir, + final String filename, + final int index) { + switch (index) { + case 0: + return "-o"; + + case 1: + String outputFileName = getOutputFileNames(filename, null)[0]; + return new File(outputDir, outputFileName) + .toString(); + + case 2: + return filename; + + default: + return null; + } + } + + /** + * Gets maximum length of command line. + * @return int maximum length of command line + */ + public int getMaximumCommandLength() { + return 1024; + } + + /** + * Gets maximum number of input files processed per command. + * @return int maximum number of input files processed per command. + */ + protected int getMaximumInputFilesPerCommand() { + return 1; + } + + /** + * Gets include directory switch. + * @param includeDir String include directory + * @return String command switch to add specified directory to search path + */ + protected String getIncludeDirSwitch(final String includeDir) { + return ""; + } + + /** + * Gets switch to define preprocessor macro. + * @param buffer StringBuffer command line argument + * @param define String macro name + * @param value String macro value, may be null. + */ + protected void getDefineSwitch(final StringBuffer buffer, + final String define, + final String value) { + } + + /** + * Gets switch to undefine preprocessor macro. + * @param buffer StringBuffer command line argument + * @param define String macro name + */ + protected void getUndefineSwitch(final StringBuffer buffer, + final String define) { + } + + /** + * Gets standard include paths. + * @return File[] standard include paths + */ + protected File[] getEnvironmentIncludePath() { + return new File[0]; + } + + /** + * Gets linker associated with this type. + * @param type LinkType linker, returns ld. + * @return Linker + */ + public Linker getLinker(final LinkType type) { + return LdLinker.getInstance(); + } + + /** + * Compiles an .ui file into the corresponding .h, .cpp and moc_*.cpp files. + * @param task current cc task + * @param outputDir output directory + * @param sourceFiles source files + * @param args command line arguments that appear before input files + * @param endArgs command line arguments that appear after input files + * @param relentless if true, do not stop at first compilation error + * @param config compiler configuration + * @param monitor progress monitor + */ + public void compile(final CCTask task, + final File outputDir, + final String[] sourceFiles, + final String[] args, + final String[] endArgs, + final boolean relentless, + final CommandLineCompilerConfiguration config, + final ProgressMonitor monitor) { + + BuildException exc = null; + String[] thisSource = new String[1]; + String[] uicCommand = new String[args.length + endArgs.length + 4]; + uicCommand[0] = "uic"; + String[] uicImplCommand = new String[args.length + endArgs.length + 6]; + uicImplCommand[0] = "uic"; + String[] mocCommand = new String[args.length + endArgs.length + 4]; + mocCommand[0] = "moc"; + for (int i = 0; i < args.length; i++) { + uicCommand[i + 1] = args[i]; + uicImplCommand[i + 1] = args[i]; + mocCommand[i + i] = args[i]; + } + uicCommand[args.length + 1] = "-o"; + uicImplCommand[args.length + 1] = "-o"; + mocCommand[args.length + 1] = "-o"; + + int uicIndex = args.length + 4; + int uicImplIndex = args.length + 6; + int mocIndex = args.length + 4; + for (int i = 0; i < endArgs.length; i++) { + uicCommand[uicIndex++] = endArgs[i]; + uicImplCommand[uicImplIndex++] = endArgs[i]; + mocCommand[mocIndex++] = endArgs[i]; + } + for (int j = 0; j < sourceFiles.length; j++) { + uicIndex = args.length + 2; + uicImplIndex = args.length + 2; + mocIndex = args.length + 2; + String[] outputFileNames = getOutputFileNames(sourceFiles[j], null); + + uicCommand[uicIndex++] = outputFileNames[0]; + uicCommand[uicIndex++] = sourceFiles[j]; + + uicImplCommand[uicImplIndex++] = outputFileNames[1]; + uicImplCommand[uicImplIndex++] = "-impl"; + uicImplCommand[uicImplIndex++] = outputFileNames[0]; + uicImplCommand[uicImplIndex++] = sourceFiles[j]; + + mocCommand[mocIndex++] = outputFileNames[2]; + mocCommand[mocIndex++] = outputFileNames[0]; + + int retval = runCommand(task, outputDir, uicCommand); + if (retval == 0) { + retval = runCommand(task, outputDir, uicImplCommand); + if (retval == 0) { + retval = runCommand(task, outputDir, mocCommand); + } + } + if (monitor != null) { + thisSource[0] = sourceFiles[j]; + monitor.progress(thisSource); + } + // + // if the process returned a failure code and + // we aren't holding an exception from an earlier + // interation + if (retval != 0 && exc == null) { + // + // construct the exception + // + exc = new BuildException(this.getCommand() + + " failed with return code " + retval, task + .getLocation()); + // + // and throw it now unless we are relentless + // + if (!relentless) { + throw exc; + } + } + } + // + // if the compiler returned a failure value earlier + // then throw an exception + if (exc != null) { + throw exc; + } + } + + /** + * Get total command line length due to the input file. + * @param outputDir File output directory + * @param inputFile String input file + * @return int characters added to command line for the input file. + */ + protected int getTotalArgumentLengthForInputFile( + final File outputDir, + final String inputFile) { + String arg1 = getInputFileArgument(outputDir, inputFile, 1); + String arg2 = getInputFileArgument(outputDir, inputFile, 2); + return arg1.length() + arg2.length() + 4; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java new file mode 100644 index 0000000..e3e309c --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/UserInterfaceParser.java @@ -0,0 +1,67 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.trolltech; + +import java.io.IOException; +import java.io.Reader; + +import net.sf.antcontrib.cpptasks.parser.Parser; + +/** + * Dependency scanner for Trolltech Qt User Interface definition files. + * + * .ui files are XML documents that may contain an include elements, + * however the includes are just copied to the generated files and + * and changes to the includes do not need to trigger rerunning uic. + * + * @author Curt Arnold + */ +public final class UserInterfaceParser + implements Parser { + + /** + * Constructor. + * + */ + public UserInterfaceParser() { + } + + /** + * Adds filename to the list of included files. + * + * @param include String included file name + */ + public void addFilename(final String include) { + } + + /** + * Gets included files. + * @return String[] included files + */ + public String[] getIncludes() { + return new String[0]; + } + + /** + * Parses source file for dependencies. + * + * @param reader Reader reader + * @throws IOException if error reading source file + */ + public void parse(final Reader reader) throws IOException { + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html new file mode 100644 index 0000000..c12d506 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/trolltech/package.html @@ -0,0 +1,27 @@ + + + + + + + +Adapters for Trolltech Qt moc and uic compilers. + + + diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java new file mode 100644 index 0000000..e428469 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java @@ -0,0 +1,104 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import org.apache.tools.ant.types.EnumeratedAttribute; +/** + * An compiler/linker command line flag. + */ +public class CommandLineArgument { + /** + * Enumerated attribute with the values "start", "mid" and "end", + */ + public static class LocationEnum extends EnumeratedAttribute { + public String[] getValues() { + return new String[]{"start", "mid", "end"}; + } + } + private String ifCond; + private int location; + private String unlessCond; + private String value; + public CommandLineArgument() { + } + public int getLocation() { + return location; + } + public String getValue() { + return value; + } + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + */ + public boolean isActive(org.apache.tools.ant.Project p) { + if (value == null) { + return false; + } + if (ifCond != null && p.getProperty(ifCond) == null) { + return false; + } else if (unlessCond != null && p.getProperty(unlessCond) != null) { + return false; + } + return true; + } + /** + * Sets the property name for the 'if' condition. + * + * The argument will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + */ + public void setIf(String propName) { + ifCond = propName; + } + /** + * Specifies relative location of argument on command line. "start" will + * place argument at start of command line, "mid" will place argument after + * all "start" arguments but before filenames, "end" will place argument + * after filenames. + * + */ + public void setLocation(LocationEnum location) { + this.location = location.getIndex(); + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the argument will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessCond = propName; + } + /** + * Specifies the string that should appear on the command line. The + * argument will be quoted if it contains embedded blanks. Use multiple + * arguments to avoid quoting. + * + */ + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java new file mode 100644 index 0000000..2137186 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/CompilerArgument.java @@ -0,0 +1,28 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +/** + * A compiler command line argument. + */ +public class CompilerArgument extends CommandLineArgument { + public CompilerArgument() { + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java new file mode 100644 index 0000000..7bc22ee --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java @@ -0,0 +1,84 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import net.sf.antcontrib.cpptasks.CUtil; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.AbstractFileSet; +import org.apache.tools.ant.types.FileSet; +/** + * An Ant FileSet object augmented with if and unless conditions. + * + * @author Curt Arnold + */ +public class ConditionalFileSet extends FileSet { + private String ifCond; + private String unlessCond; + public ConditionalFileSet() { + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** + * overrides FileSet's implementation which would throw an exception since + * the referenced object isn't this type. + */ + protected AbstractFileSet getRef(Project p) { + return (AbstractFileSet) ref.getReferencedObject(p); + } + /** + * Returns true if the Path's if and unless conditions (if any) are + * satisfied. + */ + public boolean isActive() throws BuildException { + Project p = getProject(); + if (p == null) { + throw new java.lang.IllegalStateException( + "setProject() should have been called"); + } + return CUtil.isActive(p, ifCond, unlessCond); + } + /** + * Sets the property name for the 'if' condition. + * + * The fileset will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + */ + public void setIf(String propName) { + ifCond = propName; + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the fileset will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessCond = propName; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java new file mode 100644 index 0000000..ae45eaa --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/ConditionalPath.java @@ -0,0 +1,75 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import net.sf.antcontrib.cpptasks.CUtil; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Path; +/** + * An Ant Path object augmented with if and unless conditionals + * + * @author Curt Arnold + */ +public class ConditionalPath extends Path { + private String ifCond; + private String unlessCond; + public ConditionalPath(Project project) { + super(project); + } + public ConditionalPath(Project p, String path) { + super(p, path); + } + /** + * Returns true if the Path's if and unless conditions (if any) are + * satisfied. + */ + public boolean isActive(org.apache.tools.ant.Project p) + throws BuildException { + return CUtil.isActive(p, ifCond, unlessCond); + } + /** + * Sets the property name for the 'if' condition. + * + * The path will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public void setIf(String propName) { + ifCond = propName; + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the path will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessCond = propName; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java new file mode 100644 index 0000000..5118e79 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineArgument.java @@ -0,0 +1,38 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +/** + * Preprocessor macro definition. + * + * @author Mark A Russell mark_russell@csg_systems.com + * + */ +public class DefineArgument extends UndefineArgument { + private String value; + public DefineArgument() { + super(true); + } + /** Returns the value of the define */ + public final String getValue() { + return value; + } + /** Set the value attribute */ + public final void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java new file mode 100644 index 0000000..f3ab44b --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/DefineSet.java @@ -0,0 +1,199 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; +/** + * Set of preprocessor macro defines and undefines. + * + * @author Mark A Russell mark_russell@csg_systems.com + * + * @author Adam Murdoch + */ +public class DefineSet extends DataType { + private Vector defineList = new Vector(); + private String ifCond = null; + private String unlessCond = null; + /** + * + * Adds a define element. + * + * @throws BuildException + * if reference + */ + public void addDefine(DefineArgument arg) throws BuildException { + if (isReference()) { + throw noChildrenAllowed(); + } + defineList.addElement(arg); + } + /** Adds defines/undefines. */ + private void addDefines(String[] defs, boolean isDefine) { + for (int i = 0; i < defs.length; i++) { + UndefineArgument def; + if (isDefine) { + def = new DefineArgument(); + } else { + def = new UndefineArgument(); + } + def.setName(defs[i]); + defineList.addElement(def); + } + } + /** + * + * Adds an undefine element. + * + * @throws BuildException + * if reference + */ + public void addUndefine(UndefineArgument arg) throws BuildException { + if (isReference()) { + throw noChildrenAllowed(); + } + defineList.addElement(arg); + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** Returns the defines and undefines in this set. */ + public UndefineArgument[] getDefines() throws BuildException { + if (isReference()) { + DefineSet defset = (DefineSet) getCheckedRef(DefineSet.class, + "DefineSet"); + return defset.getDefines(); + } else { + if (isActive()) { + UndefineArgument[] defs = new UndefineArgument[defineList + .size()]; + defineList.copyInto(defs); + return defs; + } else { + return new UndefineArgument[0]; + } + } + } + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + * + * @exception BuildException + * throws build exception if name is not set + */ + public final boolean isActive() throws BuildException { + return CUtil.isActive(getProject(), ifCond, unlessCond); + } + /** + * A comma-separated list of preprocessor macros to define. Use nested + * define elements to define macro values. + * + * @param defList + * comma-separated list of preprocessor macros + * @throws BuildException + * throw if defineset is a reference + */ + public void setDefine(CUtil.StringArrayBuilder defList) + throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + addDefines(defList.getValue(), true); + } + /** + * Sets a description of the current data type. + */ + public void setDescription(String desc) { + super.setDescription(desc); + } + /** + * Sets an id that can be used to reference this element. + * + * @param id + * id + */ + public void setId(String id) { + // + // this is actually accomplished by a different + // mechanism, but we can document it + // + } + /** + * Sets the property name for the 'if' condition. + * + * The define will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public final void setIf(String propName) { + ifCond = propName; + } + /** + * Specifies that this element should behave as if the content of the + * element with the matching id attribute was inserted at this location. If + * specified, no other attributes or child content should be specified, + * other than "description". + * + */ + public void setRefid(Reference r) throws BuildException { + if (!defineList.isEmpty()) { + throw tooManyAttributes(); + } + super.setRefid(r); + } + /** + * A comma-separated list of preprocessor macros to undefine. + * + * @param undefList + * comma-separated list of preprocessor macros + * @throws BuildException + * throw if defineset is a reference + */ + public void setUndefine(CUtil.StringArrayBuilder undefList) + throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + addDefines(undefList.getValue(), false); + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the define will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public final void setUnless(String propName) { + unlessCond = propName; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java b/src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java new file mode 100644 index 0000000..f710aa3 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/FlexLong.java @@ -0,0 +1,59 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import java.lang.reflect.Method; + +/** + * Helper class which can be used for Ant task attribute setter methods to + * allow the build file to specify a long in either decimal, octal, or + * hexadecimal format. + * // FlexInteger author + * @author Erik Hatcher + * @see org.apache.tools.ant.types.FlexInteger + */ +public class FlexLong { + private Long value; + /** + * Constructor used by Ant's introspection mechanism for attribute + * population + */ + public FlexLong(String value) { + // Java 1.1 did not support Long.decode().. so we call it by + // reflection. + try { + Method m = Long.class + .getMethod("decode", new Class[]{String.class}); + Object rc = m.invoke(null, new Object[]{value}); + this.value = (Long) rc; + } catch (Exception e) { + // Try it the old fashioned way, we must be on a 1.1 jre + this.value = new Long(value); + } + } + /** + * Returns the decimal integer value + */ + public long longValue() { + return value.longValue(); + } + /** + * Overridden method to return the decimal value for display + */ + public String toString() { + return value.toString(); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java b/src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java new file mode 100644 index 0000000..e4c8414 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/IncludePath.java @@ -0,0 +1,38 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import org.apache.tools.ant.Project; +/** + * An include path. + * + * Works like other paths in Ant with with the addition of "if" and "unless" + * conditions. + * + * @author Curt Arnold + */ +public class IncludePath extends ConditionalPath { + public IncludePath(Project project) { + super(project); + } + public IncludePath(Project p, String path) { + super(p, path); + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java new file mode 100644 index 0000000..acac911 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/LibrarySet.java @@ -0,0 +1,347 @@ +/* + * + * Copyright 2001-2006 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.FileVisitor; +import net.sf.antcontrib.cpptasks.compiler.Linker; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.PatternSet; +/** + * A set of library names. Libraries can also be added to a link by specifying + * them in a fileset. + * + * For most Unix-like compilers, libset will result in a series of -l and -L + * linker arguments. For Windows compilers, the library names will be used to + * locate the appropriate library files which will be added to the linkers + * input file list as if they had been specified in a fileset. + * + * @author Mark A Russell mark_russell@csg_systems.com + * + * @author Adam Murdoch + * @author Curt Arnold + */ +public class LibrarySet extends DataType { + private String dataset; + private boolean explicitCaseSensitive; + private String ifCond; + private String[] libnames; + private final FileSet set = new FileSet(); + private String unlessCond; + private LibraryTypeEnum libraryType; + public LibrarySet() { + libnames = new String[0]; + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** + * Gets the dataset. Used on OS390 if the libs are in a dataset. + * + * @return Returns a String + */ + public String getDataset() { + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + return master.getDataset(); + } + return dataset; + } + public File getDir(final Project project) { + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + return master.getDir(project); + } + return set.getDir(project); + } + protected FileSet getFileSet() { + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + return master.getFileSet(); + } + return set; + } + public String[] getLibs() { + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + return master.getLibs(); + } + String[] retval = (String[]) libnames.clone(); + return retval; + } + + /** + * Gets preferred library type + * + * @return library type, may be null. + */ + public LibraryTypeEnum getType() { + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + return master.getType(); + } + return libraryType; + } + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + */ + public boolean isActive(final org.apache.tools.ant.Project p) { + if (p == null) { + throw new NullPointerException("p"); + } + if (ifCond != null) { + String ifValue = p.getProperty(ifCond); + if (ifValue != null) { + if (ifValue.equals("no") || ifValue.equals("false")) { + throw new BuildException( + "property " + + ifCond + + " used as if condition has value " + + ifValue + + " which suggests a misunderstanding of if attributes"); + } + } else { + return false; + } + } + if (unlessCond != null) { + String unlessValue = p.getProperty(unlessCond); + if (unlessValue != null) { + if (unlessValue.equals("no") || unlessValue.equals("false")) { + throw new BuildException( + "property " + + unlessCond + + " used as unless condition has value " + + unlessValue + + " which suggests a misunderstanding of unless attributes"); + } + return false; + } + } + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + return master.isActive(project); + } + if (libnames.length == 0) { + p.log("libnames not specified or empty.", Project.MSG_WARN); + return false; + } + return true; + } + /** + * Sets case sensitivity of the file system. If not set, will default to + * the linker's case sensitivity. + * + * @param isCaseSensitive + * "true"|"on"|"yes" if file system is case sensitive, + * "false"|"off"|"no" when not. + */ + public void setCaseSensitive(final boolean isCaseSensitive) { + if (isReference()) { + throw tooManyAttributes(); + } + explicitCaseSensitive = true; + set.setCaseSensitive(isCaseSensitive); + } + /** + * Sets the dataset. Used on OS390 if the libs are in a dataset. + * + * @param dataset + * The dataset to set + */ + public void setDataset(final String dataset) { + if (isReference()) { + throw tooManyAttributes(); + } + this.dataset = dataset; + } + /** + * Library directory. + * + * @param dir + * library directory + * + */ + public void setDir(final File dir) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + set.setDir(dir); + } + /** + * Sets the property name for the 'if' condition. + * + * The library set will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public void setIf(String propName) { + ifCond = propName; + } + /** + * Comma-separated list of library names without leading prefixes, such as + * "lib", or extensions, such as ".so" or ".a". + * + */ + public void setLibs(final CUtil.StringArrayBuilder libs) throws BuildException { + if (isReference()) { + throw tooManyAttributes(); + } + libnames = libs.getValue(); + // + // earlier implementations would warn of suspicious library names + // (like libpthread for pthread or kernel.lib for kernel). + // visitLibraries now provides better feedback and ld type linkers + // should provide adequate feedback so the check here is not necessary. + } + public void setProject(final Project project) { + set.setProject(project); + super.setProject(project); + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the library set will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public void setUnless(String propName) { + unlessCond = propName; + } + + /** + * Sets the preferred library type. Supported values "shared", "static", and + * "framework". "framework" is equivalent to "shared" on non-Darwin platforms. + */ + public void setType(final LibraryTypeEnum type) { + if (isReference()) { + throw tooManyAttributes(); + } + this.libraryType = type; + } + + public void visitLibraries(final Project project, + final Linker linker, + final File[] libpath, + final FileVisitor visitor) throws BuildException { + if (isReference()) { + LibrarySet master = ((LibrarySet) getCheckedRef(LibrarySet.class, "LibrarySet")); + master.visitLibraries(project, linker, libpath, visitor); + } + // + // if there was a libs attribute then + // add the corresponding patterns to the FileSet + // + if (libnames != null) { + for (int i = 0; i < libnames.length; i++) { + String[] patterns = linker.getLibraryPatterns(new String[] { libnames[i] }, libraryType); + if (patterns.length > 0) { + FileSet localSet = (FileSet) set.clone(); + // + // unless explicitly set + // will default to the linker case sensitivity + // + if (!explicitCaseSensitive) { + boolean linkerCaseSensitive = linker.isCaseSensitive(); + localSet.setCaseSensitive(linkerCaseSensitive); + } + // + // add all the patterns for this libname + // + for (int j = 0; j < patterns.length; j++) { + PatternSet.NameEntry entry = localSet.createInclude(); + entry.setName(patterns[j]); + } + int matches = 0; + // + // if there was no specified directory then + // run through the libpath backwards + // + if (localSet.getDir(project) == null) { + // + // scan libpath in reverse order + // to give earlier entries priority + // + for (int j = libpath.length - 1; j >= 0; j--) { + FileSet clone = (FileSet) localSet.clone(); + clone.setDir(libpath[j]); + DirectoryScanner scanner = clone.getDirectoryScanner(project); + File basedir = scanner.getBasedir(); + String[] files = scanner.getIncludedFiles(); + matches += files.length; + for (int k = 0; k < files.length; k++) { + visitor.visit(basedir, files[k]); + } + } + } else { + DirectoryScanner scanner = localSet.getDirectoryScanner(project); + File basedir = scanner.getBasedir(); + String[] files = scanner.getIncludedFiles(); + matches += files.length; + for (int k = 0; k < files.length; k++) { + visitor.visit(basedir, files[k]); + } + } + // + // TODO: following section works well for Windows + // style linkers but unnecessary fails + // Unix style linkers. Will need to revisit. + // + if (matches == 0 && false) { + StringBuffer msg = new StringBuffer("No file matching "); + if (patterns.length == 1) { + msg.append("pattern ("); + msg.append(patterns[0]); + msg.append(")"); + } else { + msg.append("patterns (\""); + msg.append(patterns[0]); + for (int k = 1; k < patterns.length; k++) { + msg.append(", "); + msg.append(patterns[k]); + } + msg.append(")"); + } + msg.append(" for library name \""); + msg.append(libnames[i]); + msg.append("\" was found."); + throw new BuildException(msg.toString()); + } + } + } + } + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java b/src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java new file mode 100644 index 0000000..c0af5f8 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java @@ -0,0 +1,48 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import org.apache.tools.ant.types.EnumeratedAttribute; +/** + * Enumeration of library types for LibrarySet + * + * @author Curt Arnold + * + */ +public class LibraryTypeEnum extends EnumeratedAttribute { + /** + * Constructor + * + * Set by default to "shared" + * + * @see java.lang.Object#Object() + */ + public LibraryTypeEnum() { + setValue("shared"); + } + /** + * Gets list of acceptable values + * + * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[]{"shared", // prefer shared libraries + "static", // prefer static libraries + "framework" // framework libraries (Mac OS/X) + // equiv to shared on other platforms + }; + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java new file mode 100644 index 0000000..bee15cf --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/LinkerArgument.java @@ -0,0 +1,28 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +/** + * A linker command line argument. + */ +public class LinkerArgument extends CommandLineArgument { + public LinkerArgument() { + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java new file mode 100644 index 0000000..37a3e28 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java @@ -0,0 +1,45 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import org.apache.tools.ant.Project; +/** + * A system include path. + * + * Files located using a system include path will not participate in dependency + * analysis. + * + * Standard include paths for a compiler should not be specified since these + * should be determined from environment variables or configuration files by + * the compiler adapter. + * + * Works like other paths in Ant with with the addition of "if" and "unless" + * conditions. + * + * @author Curt Arnold + */ +public class SystemIncludePath extends ConditionalPath { + public SystemIncludePath(Project project) { + super(project); + } + public SystemIncludePath(Project p, String path) { + super(p, path); + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java new file mode 100644 index 0000000..97c4fa2 --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java @@ -0,0 +1,37 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +/** + * A set of system library names. Timestamp or location of system libraries are + * not considered in dependency analysis. + * + * Libraries can also be added to a link by specifying them in a fileset. + * + * For most Unix-like compilers, syslibset will result in a series of -l and -L + * linker arguments. For Windows compilers, the library names will be used to + * locate the appropriate library files which will be added to the linkers + * input file list as if they had been specified in a fileset. + */ +public class SystemLibrarySet extends LibrarySet { + public SystemLibrarySet() { + super(); + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } +} diff --git a/src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java b/src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java new file mode 100644 index 0000000..aa958ef --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/types/UndefineArgument.java @@ -0,0 +1,153 @@ +/* + * + * Copyright 2001-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; + +import org.apache.tools.ant.BuildException; +/** + * Preprocessor macro undefinition. + * + * @author Mark A Russell mark_russell@csg_systems.com + * + */ +public class UndefineArgument { + /** + * This method returns an array of UndefineArgument and DefineArgument's by + * merging a base list with an override list. + * + * Any define in the base list with a name that appears in the override + * list is suppressed. All entries in the override list are preserved + * + */ + public static UndefineArgument[] merge(UndefineArgument[] base, + UndefineArgument[] override) { + if (base.length == 0) { + UndefineArgument[] overrideClone = (UndefineArgument[]) override + .clone(); + return overrideClone; + } + if (override.length == 0) { + UndefineArgument[] baseClone = (UndefineArgument[]) base.clone(); + return baseClone; + } + Vector unduplicated = new Vector(base.length); + for (int i = 0; i < base.length; i++) { + UndefineArgument current = base[i]; + String currentName = current.getName(); + boolean match = false; + if (currentName == null) { + match = true; + } else { + for (int j = 0; j < override.length; j++) { + UndefineArgument over = override[j]; + String overName = over.getName(); + if (overName != null && overName.equals(currentName)) { + match = true; + break; + } + } + } + if (!match) { + unduplicated.addElement(current); + } + } + UndefineArgument[] combined = new UndefineArgument[unduplicated.size() + + override.length]; + unduplicated.copyInto(combined); + int offset = unduplicated.size(); + for (int i = 0; i < override.length; i++) { + combined[offset + i] = override[i]; + } + return combined; + } + private boolean define = false; + private String ifCond; + private String name; + private String unlessCond; + public UndefineArgument() { + } + protected UndefineArgument(boolean isDefine) { + this.define = isDefine; + } + public void execute() throws org.apache.tools.ant.BuildException { + throw new org.apache.tools.ant.BuildException( + "Not an actual task, but looks like one for documentation purposes"); + } + /** Returns the name of the define */ + public final String getName() { + return name; + } + /** Returns the value of the define */ + public String getValue() { + return null; + } + /** + * Returns true if the define's if and unless conditions (if any) are + * satisfied. + * + * @exception BuildException + * throws build exception if name is not set + */ + public final boolean isActive(org.apache.tools.ant.Project p) + throws BuildException { + if (name == null) { + throw new BuildException(" is missing name attribute"); + } + return CUtil.isActive(p, ifCond, unlessCond); + } + /** Returns true if this is a define, false if an undefine. */ + public final boolean isDefine() { + return define; + } + /** + * Sets the property name for the 'if' condition. + * + * The define will be ignored unless the property is defined. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") will throw an exception when + * evaluated. + * + * @param propName + * property name + */ + public final void setIf(String propName) { + ifCond = propName; + } + /** Set the name attribute */ + public final void setName(String name) { + this.name = name; + } + /** + * Set the property name for the 'unless' condition. + * + * If named property is set, the define will be ignored. + * + * The value of the property is insignificant, but values that would imply + * misinterpretation ("false", "no") of the behavior will throw an + * exception when evaluated. + * + * @param propName + * name of property + */ + public final void setUnless(String propName) { + unlessCond = propName; + } +} diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000..340dceb --- /dev/null +++ b/src/main/resources/META-INF/NOTICE @@ -0,0 +1,4 @@ +This product includes software developed by + The Ant-Contrib project (http://ant-contrib.sourceforge.net) +This product includes software developed by + The Apache Software Foundation (http://www.apache.org/). diff --git a/src/main/resources/cpptasks.tasks b/src/main/resources/cpptasks.tasks new file mode 100644 index 0000000..425935a --- /dev/null +++ b/src/main/resources/cpptasks.tasks @@ -0,0 +1 @@ +cc=net.sf.antcontrib.cpptasks.CCTask diff --git a/src/main/resources/cpptasks.types b/src/main/resources/cpptasks.types new file mode 100644 index 0000000..c37c17f --- /dev/null +++ b/src/main/resources/cpptasks.types @@ -0,0 +1,8 @@ +defineset=net.sf.antcontrib.cpptasks.types.DefineSet +compiler=net.sf.antcontrib.cpptasks.CompilerDef +linker=net.sf.antcontrib.cpptasks.LinkerDef +targetplatform=net.sf.antcontrib.cpptasks.TargetDef +versioninfo=net.sf.antcontrib.cpptasks.VersionInfo +distributer=net.sf.antcontrib.cpptasks.DistributerDef +syslibset=net.sf.antcontrib.cpptasks.types.SystemLibrarySet +libset=net.sf.antcontrib.cpptasks.types.LibrarySet \ No newline at end of file diff --git a/src/main/resources/net/sf/antcontrib/cpptasks/antlib.xml b/src/main/resources/net/sf/antcontrib/cpptasks/antlib.xml new file mode 100644 index 0000000..5f8af42 --- /dev/null +++ b/src/main/resources/net/sf/antcontrib/cpptasks/antlib.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/src/samples/blas.ant b/src/samples/blas.ant new file mode 100644 index 0000000..c1a28f5 --- /dev/null +++ b/src/samples/blas.ant @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/samples/check.ant b/src/samples/check.ant new file mode 100644 index 0000000..f0e1c14 --- /dev/null +++ b/src/samples/check.ant @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/samples/cppunit.ant b/src/samples/cppunit.ant new file mode 100644 index 0000000..9b0938b --- /dev/null +++ b/src/samples/cppunit.ant @@ -0,0 +1,583 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/samples/hello/build.xml b/src/samples/hello/build.xml new file mode 100644 index 0000000..b8e0b78 --- /dev/null +++ b/src/samples/hello/build.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/src/samples/hello/src/main/c/hello.c b/src/samples/hello/src/main/c/hello.c new file mode 100644 index 0000000..6912199 --- /dev/null +++ b/src/samples/hello/src/main/c/hello.c @@ -0,0 +1,25 @@ +/* + + Licensed to the Ant-Contrib Project under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The Ant-Contrib Project licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +#include + +int main(int argc, const char** argv) { + puts("Hello, World."); + return 0; +} diff --git a/src/samples/qtunit.ant b/src/samples/qtunit.ant new file mode 100644 index 0000000..fab89ed --- /dev/null +++ b/src/samples/qtunit.ant @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/samples/xercesc.ant b/src/samples/xercesc.ant new file mode 100644 index 0000000..b3072de --- /dev/null +++ b/src/samples/xercesc.ant @@ -0,0 +1,1113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/samples/xpcom.ant b/src/samples/xpcom.ant new file mode 100644 index 0000000..b1da4b2 --- /dev/null +++ b/src/samples/xpcom.ant @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt new file mode 100644 index 0000000..ac4696a --- /dev/null +++ b/src/site/apt/index.apt @@ -0,0 +1,71 @@ +~~ Licensed to the Ant-Contrib Project under one or more +~~ contributor license agreements. See the NOTICE file distributed with +~~ this work for additional information regarding copyright ownership. +~~ The Ant-Contrib Project licenses this file to You under the Apache License, Version 2.0 +~~ (the "License"); you may not use this file except in compliance with +~~ the License. You may obtain a copy of the License at +~~ +~~ http://www.apache.org/licenses/LICENSE-2.0 +~~ +~~ Unless required by applicable law or agreed to in writing, software +~~ distributed under the License is distributed on an "AS IS" BASIS, +~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +~~ See the License for the specific language governing permissions and +~~ limitations under the License. + ------ +cpptasks for Apache Ant + ------ + ------ + ------ + +cpptasks for Apache Ant + + The cc task can compile various source languages and produce executables, + shared libraries (aka DLL's) and static libraries. Compiler adaptors are currently available + for C/C++, FORTRAN, MIDL and Windows Resource compilers. + + The task can be used with Apache Ant 1.5 and later. This software is not a product + of the Apache Software Foundation (ASF) and no endorsement by the ASF is implied. + + + To use: + * Place cpptasks.jar into Ant's classpath by placing in Ant's lib directory, + adding to CLASSPATH environment variable or using the -lib command line option. + + * Add type and task definitions in build file using either taskdef or antlib. + + * Add {{{antdocs/CCTask.html}cc}} element to some target in your build file. + + * Set path and environment variables to be able to run compiler from command line. + + * Build project. + + Trivial Sample using taskdef (compatible with Ant 1.5 or later): + ++-- + + + + + + + + + ++-- + + Trivial Sample using antlib (compatible with Ant 1.6 or later): + ++-- + + + + + + + + ++-- + + More complex samples appear in src/samples. + diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 0000000..ab1d7f5 --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,69 @@ + + + + ant-contrib + http://ant-contrib.sourceforge.net/ + + + SourceForge.net Logo + http://sflogo.sourceforge.net/sflogo.php?group_id=36177&type=5 + http://www.sourceforge.net/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/xdoc/antdocs/CCTask.xml b/src/site/xdoc/antdocs/CCTask.xml new file mode 100644 index 0000000..ce994d9 --- /dev/null +++ b/src/site/xdoc/antdocs/CCTask.xml @@ -0,0 +1,534 @@ + + + + +cc + + +
+Compile and link task. + +

+ This task can compile various source languages and produce executables, + shared libraries (aka DLL's) and static libraries. Compiler adaptors are + currently available for several C/C++ compilers, FORTRAN, MIDL and Windows + Resource files. +

+ +

+ Copyright (c) 2001-2008, The Ant-Contrib project. +

+ +

+ Licensed under the Apache Software License 2.0, + http://www.apache.org/licenses/LICENSE-2.0. +

+ +

+ For use with Apache Ant 1.5 or later. This software is not a product of the + of the Apache Software Foundation and no endorsement is implied. +

+ +

+ THIS SOFTWARE IS PROVIDED 'AS-IS', See + http://www.apache.org/licenses/LICENSE-2.0 for additional disclaimers. +

+ + To use: +
    +
  1. + Place cpptasks.jar into Ant's classpath by placing it in Ant's lib + directory, adding it to the CLASSPATH environment variable or by using the + -lib command line option. +
  2. +
  3. + Add type and task definitions to the build file: +
      +
    • + Ant 1.6 or later: +
        +
      • Add xmlns:cpptasks="antlib:net.sf.antcontrib.cpptasks" to + <project> element. +
      • +
      • + Add <cpptasks:cc/>, <cpptasks:compiler/> and + <cpptasks:linker/> elements to the project. +
      • +
      +
    • +
    • + Ant 1.5 or later: +
        +
      • Add <taskdef resource="cpptasks.tasks"/> and + <typedef resource="cpptasks.types"/> to body of <project> + element. +
      • +
      • + Add <cc/>, <compiler/> and <linker/> elements to the + project. +
      • +
      +
    • +
    +
  4. +
  5. + Set the path and environment variables to be able to run compiler from + command line. +
  6. +
  7. + Build the project. +
  8. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
classnameSets the default compiler adapter. Use the "name" attribute when the + compiler is a supported compiler.String
datasetSets the dataset for OS/390 builds.String
debugEnables or disables generation of debug info.boolean
dependencydepthDeprecated. + + Controls the depth of the dependency evaluation. Used to do a quick + check of changes before a full build. + + Any negative value which will perform full dependency checking. Positive + values will truncate dependency checking. A value of 0 will cause only + those files that changed to be recompiled, a value of 1 which cause + files that changed or that explicitly include a file that changed to be + recompiled. + + Any non-negative value will cause a BuildException to be thrown before + attempting a link or completing the task.int
descriptionString
exceptionsEnables generation of exception handling codeboolean
failonerrorIndicates whether the build will continue + even if there are compilation errors; defaults to true.boolean
incrementalEnables or disables incremental linking.boolean
libtoolSet use of libtool. + + If set to true, the "libtool " will be prepended to the command line for + compatible processorsboolean
linkSets the output file type. Supported values "executable", "shared", and + "static". Deprecated, specify outtype instead. +OutputTypeEnum +
locationLocation
multithreadedEnables or disables generation of multithreaded codeboolean
nameSets type of the default compiler and linker. + + Supported compilers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
gcc (default)GCC C++ compiler
g++GCC C++ compiler
c++GCC C++ compiler
g77GNU FORTRAN compiler
msvcMicrosoft Visual C++
bccBorland C++ Compiler
msrcMicrosoft Resource Compiler
brcBorland Resource Compiler
dfCompaq Visual Fortran Compiler
midlMicrosoft MIDL Compiler
iclIntel C++ compiler for Windows (IA-32)
eclIntel C++ compiler for Windows (IA-64)
iccIntel C++ compiler for Linux (IA-32)
eccIntel C++ compiler for Linux (IA-64)
CCSun ONE C++ compiler
aCCHP aC++ C++ Compiler
os390OS390 C Compiler
os400Icc Compiler
sunc89Sun C89 C Compiler
xlCVisualAge C Compiler
uicQt user interface compiler (creates .h, .cpp and moc_*.cpp files).
mocQt meta-object compiler
xpidlMozilla xpidl compiler (creates .h and .xpt files).
wclOpenWatcom C/C++ compiler
wflOpenWatcom FORTRAN compiler
+
+CompilerEnum +
newenvironmentDo not propagate old environment when new environment variables are + specified.boolean
objdirSets the destination directory for object files. + + Generally this should be a property expression that evaluates to + distinct debug and release object file directories.File
optimizeSets optimization. +OptimizationEnum +
outfileSets the output file name. If not specified, the task will only compile + files and not attempt to link. If an extension is not specified, the + task may use a system appropriate extension and prefix, for example, + outfile="example" may result in "libexample.so" being created.File
outputfilepropertySpecifies the name of a property to set with the physical filename that + is produced by the linkerString
outtypeSets the output file type. Supported values "executable", "shared", and + "static". +OutputTypeEnum +
owningtargetTarget
projectsonlyboolean
rebuildIf set to true, all files will be rebuilt.boolean
relentlessIf set to true, compilation errors will not stop the task until all + files have been attempted.boolean
rttiEnables run-time type information.boolean
runtimeSets the type of runtime library, possible values "dynamic", "static". +RuntimeType +
subsystemSets the nature of the subsystem under which that the program will + execute. + + Supported subsystems + + + + + + + + + + + + +
guiGraphical User Interface
consoleCommand Line Console
otherOther
+
+SubsystemEnum +
tasknameString
tasktypeString
warningsEnumerated attribute with the values "none", "severe", "default", + "production", "diagnostic", and "aserror". +WarningLevelEnum +
+
+ +
+
+compiler +
+
Adds a compiler definition or reference.
+
+compilerarg +
+
Adds a compiler command-line arg. Argument will be inherited by all + nested compiler elements that do not have inherit="false".
+
+defineset +
+
Adds a defineset. Will be inherited by all compiler elements that do not + have inherit="false".
+
+distributer +
+
Adds a distributer definition or reference (Non-functional prototype).
+
+env +
+
Add an environment variable to the launched process.
+
+fileset +
+
Adds a source file set. + + Files in these filesets will be auctioned to the available compiler + configurations, with the default compiler implied by the cc element + bidding last. If no compiler is interested in the file, it will be + passed to the linker. + + To have a file be processed by a particular compiler configuration, add + a fileset to the corresponding compiler element.
+
+includepath +
+
Adds an include path. + + Include paths will be inherited by nested compiler elements that do not + have inherit="false".
+
+libset +
+
Adds a library set. + + Library sets will be inherited by all linker elements that do not have + inherit="false".
+
+linker +
+
Adds a linker definition. The first linker that is not disqualified by + its "if" and "unless" attributes will perform the link. If no child + linker element is active, the linker implied by the cc elements name or + classname attribute will be used.
+
+linkerarg +
+
Adds a linker command-line arg. Argument will be inherited by all nested + linker elements that do not have inherit="false".
+
+precompile +
+
Specifies precompilation prototype file and exclusions. Inherited by all + compilers that do not have inherit="false".
+
+project +
+
Specifies the generation of IDE project file. Experimental.
+
+sysincludepath +
+
Adds a system include path. Locations and timestamps of files located + using the system include paths are not used in dependency analysis. + + + Standard include locations should not be specified. The compiler + adapters should recognized the settings from the appropriate environment + variables or configuration files. + + System include paths will be inherited by nested compiler elements that + do not have inherit="false".
+
+syslibset +
+
Adds a system library set. Timestamps and locations of system library + sets are not used in dependency analysis. + + Essential libraries (such as C Runtime libraries) should not be + specified since the task will attempt to identify the correct libraries + based on the multithread, debug and runtime attributes. + + System library sets will be inherited by all linker elements that do not + have inherit="false".
+
+target +
+
Adds a target definition or reference (Non-functional prototype).
+
+versioninfo +
+
Adds desriptive version information to be included in the + generated file. The first active version info block will + be used.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/CommentDef.xml b/src/site/xdoc/antdocs/CommentDef.xml new file mode 100644 index 0000000..68373e9 --- /dev/null +++ b/src/site/xdoc/antdocs/CommentDef.xml @@ -0,0 +1,37 @@ + + + + +comment + + +
+Defines a comment to place in the generated project files. + +
+
+text +
+
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/CompilerArgument.xml b/src/site/xdoc/antdocs/CompilerArgument.xml new file mode 100644 index 0000000..abbf0dd --- /dev/null +++ b/src/site/xdoc/antdocs/CompilerArgument.xml @@ -0,0 +1,83 @@ + + + + +compilerarg + + +
+A compiler command line argument. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
ifSets the property name for the 'if' condition. + + The argument will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
locationSpecifies relative location of argument on command line. "start" will + place argument at start of command line, "mid" will place argument after + all "start" arguments but before filenames, "end" will place argument + after filenames. +LocationEnum +
unlessSet the property name for the 'unless' condition. + + If named property is set, the argument will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
valueSpecifies the string that should appear on the command line. The + argument will be quoted if it contains embedded blanks. Use multiple + arguments to avoid quoting.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/CompilerDef.xml b/src/site/xdoc/antdocs/CompilerDef.xml new file mode 100644 index 0000000..7d98127 --- /dev/null +++ b/src/site/xdoc/antdocs/CompilerDef.xml @@ -0,0 +1,313 @@ + + + + +compiler + + +
+A compiler definition. compiler elements may be placed either as children of + a cc element or the project element. A compiler element with an id attribute + may be referenced from compiler elements with refid or extends attributes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
classnameSets the default compiler adapter. Use the "name" attribute when the + compiler is a supported compiler.String
debugIf set true, all targets will be built for debugging.boolean
descriptionSets a description of the current data type.String
exceptionsEnables or disables exception support.boolean
extendsSpecifies that this element extends the element with id attribute with a + matching value. The configuration will be constructed from the settings + of this element, element referenced by extends, and the containing cc + element.Reference
idSets an id that can be used to reference this element.String
ifSets the property name for the 'if' condition. + + The configuration will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
inheritIf inherit has the default value of true, defines, includes and other + settings from the containing cc element will be inherited.boolean
libtoolSet use of libtool. + + If set to true, the "libtool " will be prepended to the command lineboolean
multithreadedEnables or disables generation of multithreaded code. Unless specified, + multithreaded code generation is enabled.boolean
nameSets compiler type. + + + Supported compilers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
gcc (default)GCC C++ compiler
g++GCC C++ compiler
c++GCC C++ compiler
g77GNU Fortran compiler
msvcMicrosoft Visual C++
bccBorland C++ Compiler
msrcMicrosoft Resource Compiler
brcBorland Resource Compiler
dfCompaq Visual Fortran Compiler
midlMicrosoft MIDL Compiler
iclIntel C++ compiler for Windows (IA-32)
eclIntel C++ compiler for Windows (IA-64)
iccIntel C++ compiler for Linux (IA-32)
eccIntel C++ compiler for Linux (IA-64)
CCSun ONE C++ compiler
aCCHP aC++ C++ Compiler
os390OS390 C Compiler
os400Icc Compiler
sunc89Sun C89 C Compiler
xlCVisualAge C Compiler
uicQt user interface compiler
mocQt meta-object compiler
wclOpenWatcom C/C++ compiler
wflOpenWatcom FORTRAN compiler
+
+CompilerEnum +
newenvironmentDo not propagate old environment when new environment variables are + specified.boolean
optimizeSets optimization level. +OptimizationEnum +
rebuildIf set true, all targets will be unconditionally rebuilt.boolean
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location. If + specified, no other attributes or child content should be specified, + other than "if", "unless" and "description".Reference
rttiEnables or disables run-time type information.boolean
unlessSet the property name for the 'unless' condition. + + If named property is set, the configuration will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
warningsEnumerated attribute with the values "none", "severe", "default", + "production", "diagnostic", and "aserror". +WarningLevelEnum +
+
+ +
+
+compilerarg +
+
Adds a compiler command-line arg.
+
+compilerparam +
+
Adds a compiler command-line arg.
+
+defineset +
+
Adds a defineset.
+
+env +
+
Add an environment variable to the launched process.
+
+fileset +
+
Adds a source file set. + + Files in these set will be processed by this configuration and will not + participate in the auction.
+
+includepath +
+
Creates an include path.
+
+precompile +
+
Specifies precompilation prototype file and exclusions.
+
+sysincludepath +
+
Creates a system include path. Locations and timestamps of files located + using the system include paths are not used in dependency analysis. + + + Standard include locations should not be specified. The compiler + adapters should recognized the settings from the appropriate environment + variables or configuration files.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/CompilerParam.xml b/src/site/xdoc/antdocs/CompilerParam.xml new file mode 100644 index 0000000..5a3475b --- /dev/null +++ b/src/site/xdoc/antdocs/CompilerParam.xml @@ -0,0 +1,81 @@ + + + + +compilerparam + + +
+Place class description here. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
ifSets the property name for the 'if' condition. + + The argument will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
nameSpecifies relative location of argument on command line. "start" will + place argument at start of command line, "mid" will place argument after + all "start" arguments but before filenames, "end" will place argument + after filenames.String
unlessSet the property name for the 'unless' condition. + + If named property is set, the argument will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
valueSpecifies the string that should appear on the command line. The + argument will be quoted if it contains embedded blanks. Use multiple + arguments to avoid quoting.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/ConditionalFileSet.xml b/src/site/xdoc/antdocs/ConditionalFileSet.xml new file mode 100644 index 0000000..8566212 --- /dev/null +++ b/src/site/xdoc/antdocs/ConditionalFileSet.xml @@ -0,0 +1,221 @@ + + + + +conditionalfileset + + +
+An Ant FileSet object augmented with if and unless conditions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
casesensitiveboolean
defaultexcludesboolean
descriptionString
dirFile
excludesString
excludesfileFile
fileFile
followsymlinksboolean
ifSets the property name for the 'if' condition. + + The fileset will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
includesString
includesfileFile
refidReference
unlessSet the property name for the 'unless' condition. + + If named property is set, the fileset will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+ +
+
+
+and +
+
+
+contains +
+
+
+containsregexp +
+
+
+custom +
+
+
+date +
+
+
+depend +
+
+
+depth +
+
+
+different +
+
+
+exclude +
+
+
+excludesfile +
+
+
+filename +
+
+
+include +
+
+
+includesfile +
+
+
+majority +
+
+
+modified +
+
+
+none +
+
+
+not +
+
+
+or +
+
+
+patternset +
+
+
+present +
+
+
+selector +
+
+
+size +
+
+
+type +
+
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/ConditionalPath.xml b/src/site/xdoc/antdocs/ConditionalPath.xml new file mode 100644 index 0000000..0ba7346 --- /dev/null +++ b/src/site/xdoc/antdocs/ConditionalPath.xml @@ -0,0 +1,122 @@ + + + + +conditionalpath + + +
+An Ant Path object augmented with if and unless conditionals + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionString
ifSets the property name for the 'if' condition. + + The path will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
locationFile
pathString
refidReference
unlessSet the property name for the 'unless' condition. + + If named property is set, the path will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+ +
+
+
+dirset +
+
+
+existing +
+
+
+extdirs +
+
+
+filelist +
+
+
+fileset +
+
+
+path +
+
+
+pathelement +
+
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/DebugDef.xml b/src/site/xdoc/antdocs/DebugDef.xml new file mode 100644 index 0000000..c3084e8 --- /dev/null +++ b/src/site/xdoc/antdocs/DebugDef.xml @@ -0,0 +1,76 @@ + + + + +debug + + +
+Specifies a debugging configuration for a project. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionString
dirSet the working directory of the process.File
executableSet the name of the executable program.String
refidReference
+
+ +
+
+arg +
+
Adds a command-line argument.
+
+env +
+
Add an environment variable.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/DefineArgument.xml b/src/site/xdoc/antdocs/DefineArgument.xml new file mode 100644 index 0000000..996dee8 --- /dev/null +++ b/src/site/xdoc/antdocs/DefineArgument.xml @@ -0,0 +1,76 @@ + + + + +definearg + + +
+Preprocessor macro definition. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
ifSets the property name for the 'if' condition. + + The define will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
nameSet the name attributeString
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
valueSet the value attributeString
+
+
+ +
diff --git a/src/site/xdoc/antdocs/DefineSet.xml b/src/site/xdoc/antdocs/DefineSet.xml new file mode 100644 index 0000000..50ef5ca --- /dev/null +++ b/src/site/xdoc/antdocs/DefineSet.xml @@ -0,0 +1,111 @@ + + + + +defineset + + +
+Set of preprocessor macro defines and undefines. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
defineA comma-separated list of preprocessor macros to define. Use nested + define elements to define macro values. +StringArrayBuilder +
descriptionSets a description of the current data type.String
idSets an id that can be used to reference this element.String
ifSets the property name for the 'if' condition. + + The define will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location. If + specified, no other attributes or child content should be specified, + other than "description".Reference
undefineA comma-separated list of preprocessor macros to undefine. +StringArrayBuilder +
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+define +
+
Adds a define element.
+
+undefine +
+
Adds an undefine element.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/DependencyDef.xml b/src/site/xdoc/antdocs/DependencyDef.xml new file mode 100644 index 0000000..d0fd35b --- /dev/null +++ b/src/site/xdoc/antdocs/DependencyDef.xml @@ -0,0 +1,64 @@ + + + + +dependency + + +
+Defines a dependency + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
dependsString
fileFile
idString
nameString
+
+
+ +
diff --git a/src/site/xdoc/antdocs/DistributerDef.xml b/src/site/xdoc/antdocs/DistributerDef.xml new file mode 100644 index 0000000..3530039 --- /dev/null +++ b/src/site/xdoc/antdocs/DistributerDef.xml @@ -0,0 +1,113 @@ + + + + +distributer + + +
+Distributed build information (Non-functional prototype). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionString
hostsSets hosts.String
idSets an id that can be used to reference this element.String
ifSets the property name for the 'if' condition. + + The define will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
protocolSets protocol. +DistributerProtocolEnum +
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location. If + specified, no other attributes should be specified.Reference
tcpcorkSets TCP_CORK value.int
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
userSets remote user name.String
+
+ +
+
+map +
+
Local to remote filename maps.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/DistributerMap.xml b/src/site/xdoc/antdocs/DistributerMap.xml new file mode 100644 index 0000000..fa7be49 --- /dev/null +++ b/src/site/xdoc/antdocs/DistributerMap.xml @@ -0,0 +1,96 @@ + + + + +distributermap + + +
+Local to remote filename mapping (Experimental). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionString
hostsSets hosts for which this mapping is valid.String
ifSets the property name for the 'if' condition. + + This object will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
localSets local directory for base of mapping.File
refidReference
remoteSets remote name for directory.String
remoteseparatorSets the separator character (/ or \) for the remote system.String
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/IncludePath.xml b/src/site/xdoc/antdocs/IncludePath.xml new file mode 100644 index 0000000..a50ec2a --- /dev/null +++ b/src/site/xdoc/antdocs/IncludePath.xml @@ -0,0 +1,125 @@ + + + + +includepath + + +
+An include path. + + Works like other paths in Ant with with the addition of "if" and "unless" + conditions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionString
ifSets the property name for the 'if' condition. + + The path will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
locationFile
pathString
refidReference
unlessSet the property name for the 'unless' condition. + + If named property is set, the path will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+ +
+
+
+dirset +
+
+
+existing +
+
+
+extdirs +
+
+
+filelist +
+
+
+fileset +
+
+
+path +
+
+
+pathelement +
+
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/LibrarySet.xml b/src/site/xdoc/antdocs/LibrarySet.xml new file mode 100644 index 0000000..095a182 --- /dev/null +++ b/src/site/xdoc/antdocs/LibrarySet.xml @@ -0,0 +1,114 @@ + + + + +libset + + +
+A set of library names. Libraries can also be added to a link by specifying + them in a fileset. + + For most Unix-like compilers, libset will result in a series of -l and -L + linker arguments. For Windows compilers, the library names will be used to + locate the appropriate library files which will be added to the linkers + input file list as if they had been specified in a fileset. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
casesensitiveSets case sensitivity of the file system. If not set, will default to + the linker's case sensitivity.boolean
datasetSets the dataset. Used on OS390 if the libs are in a dataset.String
descriptionString
dirLibrary directory.File
ifSets the property name for the 'if' condition. + + The library set will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
libsComma-separated list of library names without leading prefixes, such as + "lib", or extensions, such as ".so" or ".a". +StringArrayBuilder +
refidReference
typeSets the preferred library type. Supported values "shared", "static", and + "framework". "framework" is equivalent to "shared" on non-Darwin platforms. +LibraryTypeEnum +
unlessSet the property name for the 'unless' condition. + + If named property is set, the library set will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/LinkerArgument.xml b/src/site/xdoc/antdocs/LinkerArgument.xml new file mode 100644 index 0000000..94b64d2 --- /dev/null +++ b/src/site/xdoc/antdocs/LinkerArgument.xml @@ -0,0 +1,83 @@ + + + + +linkerarg + + +
+A linker command line argument. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
ifSets the property name for the 'if' condition. + + The argument will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
locationSpecifies relative location of argument on command line. "start" will + place argument at start of command line, "mid" will place argument after + all "start" arguments but before filenames, "end" will place argument + after filenames. +LocationEnum +
unlessSet the property name for the 'unless' condition. + + If named property is set, the argument will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
valueSpecifies the string that should appear on the command line. The + argument will be quoted if it contains embedded blanks. Use multiple + arguments to avoid quoting.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/LinkerDef.xml b/src/site/xdoc/antdocs/LinkerDef.xml new file mode 100644 index 0000000..32e802f --- /dev/null +++ b/src/site/xdoc/antdocs/LinkerDef.xml @@ -0,0 +1,284 @@ + + + + +linker + + +
+A linker definition. linker elements may be placed either as children of a + cc element or the project element. A linker element with an id attribute may + be referenced by linker elements with refid or extends attributes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
baseSets the base address. May be specified in either decimal or hex. +FlexLong +
classnameSets the class name for the adapter. Use the "name" attribute when the + tool is supported.String
debugIf set true, all targets will be built for debugging.boolean
descriptionSets a description of the current data type.String
entrySets the starting address.String
extendsSpecifies that this element extends the element with id attribute with a + matching value. The configuration will be constructed from the settings + of this element, element referenced by extends, and the containing cc + element.Reference
fixedIf true, marks the file to be loaded only at its preferred address.boolean
idSets an id that can be used to reference this element.String
ifSets the property name for the 'if' condition. + + The configuration will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
incrementalIf true, allows incremental linking.boolean
inheritIf inherit has the default value of true, defines, includes and other + settings from the containing cc element will be inherited.boolean
libtoolSet use of libtool. + + If set to true, the "libtool " will be prepended to the command lineboolean
mapIf set to true, a map file will be produced.boolean
nameSets linker type. + + + Supported linkers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
gccGcc Linker
g++G++ Linker
ldLd Linker
arGcc Librarian
msvcMicrosoft Linker
bccBorland Linker
dfCompaq Visual Fortran Linker
iclIntel Linker for Windows (IA-32)
eclIntel Linker for Windows (IA-64)
iccIntel Linker for Linux (IA-32)
eccIntel Linker for Linux (IA-64)
CCSun ONE Linker
aCCHP aC++ Linker
os390OS390 Linker
os390batchOS390 Linker
os400IccLinker
sunc89C89 Linker
xlCVisualAge Linker
wclOpenWatcom C/C++ linker
wflOpenWatcom FORTRAN linker
+
+LinkerEnum +
newenvironmentDo not propagate old environment when new environment variables are + specified.boolean
rebuildIf set true, all targets will be unconditionally rebuilt.boolean
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location. If + specified, no other attributes or child content should be specified, + other than "if", "unless" and "description".Reference
stackSets stack size in bytes.FlexInteger
unlessSet the property name for the 'unless' condition. + + If named property is set, the configuration will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+env +
+
Add an environment variable to the launched process.
+
+fileset +
+
Adds a source file set. + + Files in these set will be processed by this configuration and will not + participate in the auction.
+
+libset +
+
Adds a system library set.
+
+linkerarg +
+
Adds a linker command-line arg.
+
+linkerparam +
+
Adds a compiler command-line arg.
+
+syslibset +
+
Adds a system library set.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/LinkerParam.xml b/src/site/xdoc/antdocs/LinkerParam.xml new file mode 100644 index 0000000..e5ad6a7 --- /dev/null +++ b/src/site/xdoc/antdocs/LinkerParam.xml @@ -0,0 +1,81 @@ + + + + +linkerparam + + +
+Place class description here. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
ifSets the property name for the 'if' condition. + + The argument will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
nameSpecifies relative location of argument on command line. "start" will + place argument at start of command line, "mid" will place argument after + all "start" arguments but before filenames, "end" will place argument + after filenames.String
unlessSet the property name for the 'unless' condition. + + If named property is set, the argument will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
valueSpecifies the string that should appear on the command line. The + argument will be quoted if it contains embedded blanks. Use multiple + arguments to avoid quoting.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/PrecompileDef.xml b/src/site/xdoc/antdocs/PrecompileDef.xml new file mode 100644 index 0000000..5b700f7 --- /dev/null +++ b/src/site/xdoc/antdocs/PrecompileDef.xml @@ -0,0 +1,99 @@ + + + + +precompile + + +
+An element that specifies a prototype file and rules for source files that + should not use precompiled headers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionSets a description of the current data type.String
idSets an id that can be used to reference this element.String
ifSet the 'if' condition. + + The processor will be ignored unless the property is defined. + + The value of property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + isActive() is evaluated.String
prototypeSets file to precompile. + + Should be a source file that includes only one unguarded header file. + Default value is "stdafx.cpp".File
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location.Reference
unlessSet the 'unless' condition. If named property exists at execution time, + the processor will be ignored. + + Value of property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when isActive is called.String
+
+ +
+
+except +
+
Adds filesets that specify files that should not be processed with + precompiled headers enabled.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/PrecompileExceptDef.xml b/src/site/xdoc/antdocs/PrecompileExceptDef.xml new file mode 100644 index 0000000..f645473 --- /dev/null +++ b/src/site/xdoc/antdocs/PrecompileExceptDef.xml @@ -0,0 +1,64 @@ + + + + +precompileexcept + + +
+Specifies files that should not be compiled using precompiled headers. + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
dirSets the base-directoryFile
includesComma or space separated list of file patterns that should not be + compiled using precompiled headers.String
+
+ +
+
+fileset +
+
Adds filesets that specify files that should not be processed using + precompiled headers.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/ProjectDef.xml b/src/site/xdoc/antdocs/ProjectDef.xml new file mode 100644 index 0000000..ebafe48 --- /dev/null +++ b/src/site/xdoc/antdocs/ProjectDef.xml @@ -0,0 +1,166 @@ + + + + +project + + +
+Requests the creation of an IDE project file. Experimental. + + Implementation status: msdev5, msdev6 and cbuilderx + generate reasonable project files for simple projects, + xcode and msdev7 and msdev71 capture source file lists and + a few settings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
classnameClass name for a user-supplied project writer. Use the "type" + attribute to specify built-in project writer implementations.String
descriptionString
failonerrorSets whether a failure to write the project file should cause the + task to fail. Default is true.boolean
ifSets the property name for the 'if' condition. + + The configuration will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
nameSet name.String
outfileSets the name for the generated project file.File
overwriteSets whether an existing project file should be overwritten, + default is true. If false and the project file exists, + the value of failonerror will determine if the task fails.boolean
refidReference
typeSet project type. + + + Supported project formats + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
cbuilderxBorland C++BuilderX
msvc5Microsoft Visual C++ 97
msvc6Microsoft Visual C++ 6
msvc7Microsoft Visual C++.NET
msvc71Microsoft Visual C++.NET 2003
msvc8Microsoft Visual C++ 2005
msvc9Microsoft Visual C++ 2008
xcodeApple Xcode
+
+ProjectWriterEnum +
unlessSet the property name for the 'unless' condition. + + If named property is set, the configuration will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+comment +
+
Add comment for the generated project file.
+
+dependency +
+
Add a dependency definition to the project.
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/SystemIncludePath.xml b/src/site/xdoc/antdocs/SystemIncludePath.xml new file mode 100644 index 0000000..0bb789f --- /dev/null +++ b/src/site/xdoc/antdocs/SystemIncludePath.xml @@ -0,0 +1,132 @@ + + + + +systemincludepath + + +
+A system include path. + + Files located using a system include path will not participate in dependency + analysis. + + Standard include paths for a compiler should not be specified since these + should be determined from environment variables or configuration files by + the compiler adapter. + + Works like other paths in Ant with with the addition of "if" and "unless" + conditions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
descriptionString
ifSets the property name for the 'if' condition. + + The path will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
locationFile
pathString
refidReference
unlessSet the property name for the 'unless' condition. + + If named property is set, the path will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+ +
+
+ +
+
+
+dirset +
+
+
+existing +
+
+
+extdirs +
+
+
+filelist +
+
+
+fileset +
+
+
+path +
+
+
+pathelement +
+
+
+
+
+ +
diff --git a/src/site/xdoc/antdocs/SystemLibrarySet.xml b/src/site/xdoc/antdocs/SystemLibrarySet.xml new file mode 100644 index 0000000..0a9b566 --- /dev/null +++ b/src/site/xdoc/antdocs/SystemLibrarySet.xml @@ -0,0 +1,116 @@ + + + + +syslibset + + +
+A set of system library names. Timestamp or location of system libraries are + not considered in dependency analysis. + + Libraries can also be added to a link by specifying them in a fileset. + + For most Unix-like compilers, syslibset will result in a series of -l and -L + linker arguments. For Windows compilers, the library names will be used to + locate the appropriate library files which will be added to the linkers + input file list as if they had been specified in a fileset. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
casesensitiveSets case sensitivity of the file system. If not set, will default to + the linker's case sensitivity.boolean
datasetSets the dataset. Used on OS390 if the libs are in a dataset.String
descriptionString
dirLibrary directory.File
ifSets the property name for the 'if' condition. + + The library set will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
libsComma-separated list of library names without leading prefixes, such as + "lib", or extensions, such as ".so" or ".a". +StringArrayBuilder +
refidReference
typeSets the preferred library type. Supported values "shared", "static", and + "framework". "framework" is equivalent to "shared" on non-Darwin platforms. +LibraryTypeEnum +
unlessSet the property name for the 'unless' condition. + + If named property is set, the library set will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/TargetDef.xml b/src/site/xdoc/antdocs/TargetDef.xml new file mode 100644 index 0000000..6274cf7 --- /dev/null +++ b/src/site/xdoc/antdocs/TargetDef.xml @@ -0,0 +1,105 @@ + + + + +targetplatform + + +
+Information on the execution platforms for the generated code. + (Non-functional prototype) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
archSets cpu architecture, compiler may use cpu specific instructions. +ArchEnum +
cpuSets preferred cpu, but does not use cpu specific instructions. +CPUEnum +
descriptionSets a description of the current data type.String
idSets an id that can be used to reference this element.String
ifSets the property name for the 'if' condition. + + The define will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
osfamilySets operating system family. +OSFamilyEnum +
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location. If + specified, no other attributes should be specified.Reference
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/UndefineArgument.xml b/src/site/xdoc/antdocs/UndefineArgument.xml new file mode 100644 index 0000000..533e227 --- /dev/null +++ b/src/site/xdoc/antdocs/UndefineArgument.xml @@ -0,0 +1,71 @@ + + + + +undefinearg + + +
+Preprocessor macro undefinition. + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
ifSets the property name for the 'if' condition. + + The define will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
nameSet the name attributeString
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+
+ +
diff --git a/src/site/xdoc/antdocs/VersionInfo.xml b/src/site/xdoc/antdocs/VersionInfo.xml new file mode 100644 index 0000000..37fd97b --- /dev/null +++ b/src/site/xdoc/antdocs/VersionInfo.xml @@ -0,0 +1,187 @@ + + + + +versioninfo + + +
+Version Information. + + This information is applied in a platform specific manner + to embed version information into executable images. This + behavior is new and subject to change. + + On the Microsoft Windows platform, a resource is generated and added + to the set of files to be compiled. A resource compiler must + be specified to compile the generated file. + + On Unix platforms, versioninfo is currently not used. + Future versions may append fileversion to the output file name, + use compatibility version for -soname and possibly create + symbolic links. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Attribute + +Description + +Type +
companynameSets company name.String
compatibilityversionSets compatibility version.String
descriptionString
extendsSpecifies that this element extends the element with id attribute with a + matching value. The configuration will be constructed from the settings + of this element, element referenced by extends, and the containing cc + element.Reference
filecommentsSets comments.String
filedescriptionSets file description.String
fileversionSets file version.String
idSets an id that can be used to reference this element.String
ifSets the property name for the 'if' condition. + + The define will be ignored unless the property is defined. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") will throw an exception when + evaluated.String
internalnameSets internal name. Internal name will automatically be + specified from build step, only set this value if + intentionally overriding that value.String
languageSets language.String
legalcopyrightSets legal copyright.String
legaltrademarksSets legal trademark.String
originalfilenameSets original name. Only set this value if + intentionally overriding the value from the build set.String
patchedSets prerelease.boolean
prereleaseSets prerelease.boolean
privatebuildSets private build.String
productnameSets product name.String
productversionSets product version.String
refidSpecifies that this element should behave as if the content of the + element with the matching id attribute was inserted at this location. If + specified, no other attributes should be specified.Reference
specialbuildSets private build.String
unlessSet the property name for the 'unless' condition. + + If named property is set, the define will be ignored. + + The value of the property is insignificant, but values that would imply + misinterpretation ("false", "no") of the behavior will throw an + exception when evaluated.String
+
+
+ +
diff --git a/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java b/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java new file mode 100644 index 0000000..8d22928 --- /dev/null +++ b/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java @@ -0,0 +1 @@ +/* Licensed to the Ant-Contrib Project under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The Ant-Contrib Project licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package net.sf.antcontrib.taskdocs; import com.sun.javadoc.*; import org.xml.sax.*; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Source; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.File; import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; /** * This document writes an XML representation of the * Ant related Javadoc through an XSLT transform that creates xdoc files. * */ public final class TaskDoclet { /** * Process Javadoc content. * @param root root of javadoc content. * @return true if successful * @throws Exception IO exceptions and the like. */ public static boolean start(RootDoc root) throws Exception { SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); Source typeStyle = new StreamSource(new File("src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt")); // // replace with tf.newTransformerHandler() if you want to see raw generated XML. TransformerHandler typeHandler = tf.newTransformerHandler(typeStyle); Map referencedTypes = new HashMap(); Map documentedTypes = new HashMap(); ClassDoc[] classes = root.classes(); for (int i = 0; i < classes.length; ++i) { ClassDoc clazz = classes[i]; if (clazz.isPublic() && !clazz.isAbstract()) { if (isTask(clazz) || isType(clazz)) { writeClass(typeHandler, clazz, referencedTypes); documentedTypes.put(clazz.qualifiedTypeName(), clazz); } } } Map additionalTypes = new HashMap(); for (Iterator iter = referencedTypes.keySet().iterator(); iter.hasNext();) { String referencedName = (String) iter.next(); if (documentedTypes.get(referencedName) == null) { ClassDoc referencedClass = root.classNamed(referencedName); if (referencedClass != null) { if (!referencedClass.qualifiedTypeName().startsWith("org.apache.tools.ant")) { writeClass(typeHandler, referencedClass, additionalTypes); documentedTypes.put(referencedClass.qualifiedTypeName(), referencedClass); } } } } return true; } /** * Determine if class is an Ant task. * @param clazz class to test. * @return true if class is an Ant task. */ private static boolean isTask(final ClassDoc clazz) { if (clazz == null) return false; if ("org.apache.tools.ant.Task".equals(clazz.qualifiedTypeName())) { System.out.print("true"); return true; } return isTask(clazz.superclass()); } /** * Determine if class is an Ant type. * @param clazz class to test. * @return true if class is an Ant type. */ private static boolean isType(final ClassDoc clazz) { if (clazz == null) return false; if ("org.apache.tools.ant.types.DataType".equals(clazz.qualifiedTypeName())) { return true; } return isType(clazz.superclass()); } /** * Namespace URI for class description elements. */ private static final String NS_URI = "http://ant-contrib.sf.net/taskdocs"; /** * Namespace URI for XHTML elements. */ private static final String XHTML_URI = "http://www.w3.org/1999/xhtml"; /** * Write a Java type. * @param tf content handler. * @param type documented type. * @throws Exception if IO or other exception. */ private static void writeType(final TransformerHandler tf, final Type type) throws Exception { AttributesImpl attributes = new AttributesImpl(); attributes.addAttribute(null, "name", "name", "CDATA", type.simpleTypeName()); attributes.addAttribute(null, "qualifiedTypeName", "qualifiedTypeName", "CDATA", type.qualifiedTypeName()); tf.startElement(NS_URI, "type", "type", attributes); ClassDoc typeDoc = type.asClassDoc(); if (typeDoc != null && typeDoc.commentText() != null && typeDoc.commentText().length() > 0) { writeDescription(tf, typeDoc.commentText()); } else { tf.characters(type.typeName().toCharArray(), 0, type.typeName().length()); } tf.endElement(NS_URI, "type", "type"); } /** * Write an Ant task or type attribute (aka property). * @param tf content handler. * @param method set method for property. * @throws Exception if IO or other exception. */ private static void writeAttribute(final TransformerHandler tf, final MethodDoc method) throws Exception { AttributesImpl attributes = new AttributesImpl(); attributes.addAttribute(null, "name", "name", "CDATA", method.name().substring(3).toLowerCase(Locale.US)); tf.startElement(NS_URI, "attribute", "attribute", attributes); writeType(tf, method.parameters()[0].type()); attributes.clear(); tf.startElement(NS_URI, "comment", "comment", attributes); writeDescription(tf, method.commentText()); tf.endElement(NS_URI, "comment", "comment"); tf.endElement(NS_URI, "attribute", "attribute"); } /** * Write an Ant nested element. * @param tf content handler. * @param method method to add element to task or type. * @param name name of nested element. * @param type type of nested element. * @param referencedTypes map of types referenced in documentation. * @throws Exception if IO or other exception. */ private static void writeChild(final TransformerHandler tf, final MethodDoc method, final String name, final Type type, final Map referencedTypes) throws Exception { AttributesImpl attributes = new AttributesImpl(); attributes.addAttribute(null, "name", "name", "CDATA", name.toLowerCase(Locale.US)); tf.startElement(NS_URI, "child", "child", attributes); attributes.clear(); tf.startElement(NS_URI, "comment", "comment", attributes); writeDescription(tf, method.commentText()); tf.endElement(NS_URI, "comment", "comment"); writeType(tf, type); tf.endElement(NS_URI, "child", "child"); referencedTypes.put(type.qualifiedTypeName(), type); } /** * Redirects parsed XHTML comment into output stream. * Drops start and end document and body element. */ private static class RedirectHandler extends DefaultHandler { /** * output handler. */ private final ContentHandler tf; /** * Create new instance. * @param tf output handler, may not be null. */ public RedirectHandler(final TransformerHandler tf) { if (tf == null) { throw new IllegalArgumentException("tf"); } this.tf = tf; } /** {@inheritDoc} */ public void characters(final char[] ch, final int start, final int length) throws SAXException { tf.characters(ch, start, length); } /** {@inheritDoc} */ public void endDocument() { } /** {@inheritDoc} */ public void endElement(final String namespaceURI, final String localName, final String qName) throws SAXException { if (!"body".equals(localName)) { tf.endElement(namespaceURI, localName, qName); } } /** {@inheritDoc} */ public void endPrefixMapping(final String prefix) throws SAXException { tf.endPrefixMapping(prefix); } /** {@inheritDoc} */ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { tf.ignorableWhitespace(ch, start, length); } /** {@inheritDoc} */ public void processingInstruction(final String target, final String data) throws SAXException { tf.processingInstruction(target, data); } /** {@inheritDoc} */ public void setDocumentLocator(final Locator locator) { tf.setDocumentLocator(locator); } /** {@inheritDoc} */ public void skippedEntity(String name) throws SAXException { tf.skippedEntity(name); } /** {@inheritDoc} */ public void startDocument() { } /** {@inheritDoc} */ public void startElement(final String namespaceURI, final String localName, final String qName, final Attributes atts) throws SAXException { if (!"body".equals(localName)) { tf.startElement(namespaceURI, localName, qName, atts); } } /** {@inheritDoc} */ public void startPrefixMapping(String prefix, String uri) throws SAXException { tf.startPrefixMapping(prefix, uri); } } /** * Writes description. * @param tf destination. * @param description description, may contain XHTML elements. * @throws SAXException if IO or other exception. */ private static void writeDescription(final TransformerHandler tf, final String description) throws SAXException { if (description.indexOf('<') == -1) { tf.characters(description.toCharArray(), 0, description.length()); } else { // // attempt to fabricate an XHTML fragment // StringBuffer buf = new StringBuffer(description); buf.insert(0, ""); buf.append(""); try { SAXParserFactory sf = SAXParserFactory.newInstance(); sf.setNamespaceAware(true); SAXParser parser = sf.newSAXParser(); parser.parse(new InputSource(new StringReader(buf.toString())), new RedirectHandler(tf)); } catch (Exception ex) { tf.characters(ex.toString().toCharArray(), 0, ex.toString().length()); } } } /** * Write all Ant attributes in this class and superclasses. * @param tf destination. * @param clazz class documentation. * @param processed map of processed methods. * @param referencedTypes map of referenced types. * @throws Exception if IO or other exception. */ private static void writeAttributes(final TransformerHandler tf, final ClassDoc clazz, final Map processed, final Map referencedTypes) throws Exception { MethodDoc[] methods = clazz.methods(); for (int i = 0; i < methods.length; i++) { MethodDoc method = methods[i]; if (processed.get(method.name()) == null) { if (method.name().startsWith("set") && method.isPublic() && method.parameters().length == 1) { writeAttribute(tf, method); referencedTypes.put(method.parameters()[0].typeName(), method.parameters()[0].type()); } processed.put(method.name(), method); } } if (clazz.superclass() != null) { writeAttributes(tf, clazz.superclass(), processed, referencedTypes); } } /** * Write all Ant nested elements in this class and superclasses. * @param tf destination. * @param clazz class documentation. * @param processed map of processed methods. * @param referencedTypes map of referenced types. * @throws Exception if IO or other exception. */ private static final void writeChildren(final TransformerHandler tf, final ClassDoc clazz, final Map processed, final Map referencedTypes) throws Exception { MethodDoc[] methods = clazz.methods(); for (int i = 0; i < methods.length; i++) { MethodDoc method = methods[i]; if (processed.get(method.name()) == null) { if (method.name().startsWith("addConfigured") && method.isPublic() && method.parameters().length == 1) { writeChild(tf, method, method.name().substring(13), method.parameters()[0].type(), referencedTypes); } else if (method.name().startsWith("add") && method.isPublic() && method.parameters().length == 1) { writeChild(tf, method, method.name().substring(3), method.parameters()[0].type(), referencedTypes); } else if (method.isPublic() && method.parameters().length == 0 && method.name().startsWith("create")) { writeChild(tf, method, method.name().substring(6), method.returnType(), referencedTypes); } processed.put(method.name(), method); } } if (clazz.superclass() != null) { writeChildren(tf, clazz.superclass(), processed, referencedTypes); } } /** * Write Ant documentation for this class. * @param tf destination. * @param clazz class documentation. * @param referencedTypes map of referenced types. * @throws Exception if IO or other exception. */ private static void writeClass(final TransformerHandler tf, final ClassDoc clazz, final Map referencedTypes) throws Exception { StreamResult result = new StreamResult(new File("src/site/xdoc/antdocs/" + clazz.name() + ".xml")); tf.setResult(result); AttributesImpl attributes = new AttributesImpl(); attributes.addAttribute(null, "name", "name", "CDATA", clazz.name()); StringBuffer firstSentence = new StringBuffer(); Tag[] tags = clazz.firstSentenceTags(); for (int i = 0; i < tags.length; i++) { firstSentence.append(tags[i].text()); } if (firstSentence.length() > 0) { attributes.addAttribute(null, "firstSentence", "firstSentence", "CDATA", firstSentence.toString()); } tf.startDocument(); tf.startElement(NS_URI, "class", "class", attributes); attributes.clear(); tf.startElement(NS_URI, "comment", "comment", attributes); writeDescription(tf, clazz.commentText()); tf.endElement(NS_URI, "comment", "comment"); tf.startElement(NS_URI, "attributes", "attributes", attributes); Map methods = new HashMap(); methods.put("setProject", "setProject"); methods.put("setRuntimeConfigurableWrapper", "setRuntimeConfigurableWrapper"); writeAttributes(tf, clazz, methods, referencedTypes); tf.endElement(NS_URI, "attributes", "attributes"); tf.startElement(NS_URI, "children", "children", attributes); Map children = new HashMap(); writeChildren(tf, clazz, children, referencedTypes); tf.endElement(NS_URI, "children", "children"); tf.endElement(NS_URI, "class", "class"); tf.endDocument(); } } \ No newline at end of file diff --git a/src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt b/src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt new file mode 100644 index 0000000..b489247 --- /dev/null +++ b/src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt @@ -0,0 +1,210 @@ + + + + + + + + + + + +Licensed to the Ant-Contrib Project under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The Ant-Contrib Project licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + + + + + + + + + + + + + + + + + + syslibset + libset + targetplatform + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name='pretty-name'> + <xsl:with-param name="name"> + <xsl:value-of select="@name"/> + </xsl:with-param> + </xsl:call-template> + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionType
+
+
+ + +
+ + + +
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .html + http://ant.apache.org/manual/CoreTypes/patternset.html + http://ant.apache.org/manual/using.html#path + http://ant.apache.org/manual/CoreTasks/exec.html + about:blank + + + + + + + +
+ + + + + + + + + + +
+
+
+ + +
diff --git a/src/test/java/net/sf/antcontrib/cpptasks/MockBuildListener.java b/src/test/java/net/sf/antcontrib/cpptasks/MockBuildListener.java new file mode 100644 index 0000000..e7bd999 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/MockBuildListener.java @@ -0,0 +1,172 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.util.Vector; + +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; +/** + * Captures build events + * + */ +public class MockBuildListener implements BuildListener { + private Vector buildFinishedEvents = new Vector(); + private Vector buildStartedEvents = new Vector(); + private Vector messageLoggedEvents = new Vector(); + private Vector targetFinishedEvents = new Vector(); + private Vector targetStartedEvents = new Vector(); + private Vector taskFinishedEvents = new Vector(); + private Vector taskStartedEvents = new Vector(); + /** + * Signals that the last target has finished. This event will still be + * fired if an error occurred during the build. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + * + * @see BuildEvent#getException() + */ + public void buildFinished(BuildEvent event) { + buildFinishedEvents.addElement(event); + } + /** + * Signals that a build has started. This event is fired before any targets + * have started. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + */ + public void buildStarted(BuildEvent event) { + buildStartedEvents.addElement(event); + } + public Vector getBuildFinishedEvents() { + return new Vector(buildFinishedEvents); + } + /** + * Gets a list of buildStarted events + * + * @return list of build started events + */ + public Vector getBuildStartedEvents() { + return new Vector(buildStartedEvents); + } + /** + * Gets message logged events + * + * @return vector of "MessageLogged" events. + */ + public Vector getMessageLoggedEvents() { + return new Vector(messageLoggedEvents); + } + /** + * Gets target finished events + * + * @return vector of "TargetFinished" events. + */ + public Vector getTargetFinishedEvents() { + return new Vector(targetFinishedEvents); + } + /** + * Gets target started events + * + * @return vector of "TargetStarted" events. + */ + public Vector getTargetStartedEvents() { + return new Vector(targetStartedEvents); + } + /** + * Gets task finished events + * + * @return vector of "TaskFinished" events. + */ + public Vector getTaskFinishedEvents() { + return new Vector(taskFinishedEvents); + } + /** + * Gets task started events + * + * @return vector of "TaskStarted" events. + */ + public Vector getTaskStartedEvents() { + return new Vector(taskStartedEvents); + } + /** + * Signals a message logging event. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + * + * @see BuildEvent#getMessage() + * @see BuildEvent#getPriority() + */ + public void messageLogged(BuildEvent event) { + messageLoggedEvents.addElement(event); + } + /** + * Signals that a target has finished. This event will still be fired if an + * error occurred during the build. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + * + * @see BuildEvent#getException() + */ + public void targetFinished(BuildEvent event) { + targetFinishedEvents.addElement(event); + } + /** + * Signals that a target is starting. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + * + * @see BuildEvent#getTarget() + */ + public void targetStarted(BuildEvent event) { + targetStartedEvents.addElement(event); + } + /** + * Signals that a task has finished. This event will still be fired if an + * error occurred during the build. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + * + * @see BuildEvent#getException() + */ + public void taskFinished(BuildEvent event) { + taskFinishedEvents.addElement(event); + } + /** + * Signals that a task is starting. + * + * @param event + * An event with any relevant extra information. Must not be + * null. + * + * @see BuildEvent#getTask() + */ + public void taskStarted(BuildEvent event) { + taskStartedEvents.addElement(event); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/MockFileCollector.java b/src/test/java/net/sf/antcontrib/cpptasks/MockFileCollector.java new file mode 100644 index 0000000..d1768fd --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/MockFileCollector.java @@ -0,0 +1,90 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Implementation of FileVisitor that collects visited files for later + * retrieval. + * + * @author Curt Arnold + * + */ +public final class MockFileCollector + implements FileVisitor { + + /** + * list of fileName parameter values. + */ + private final List fileNames = new ArrayList(); + + /** + * list of baseDir parameter values. + */ + private final List baseDirs = new ArrayList(); + + /** + * Constructor. + * + */ + public MockFileCollector() { + } + + /** + * Implementation of FileVisitor.visit. + * @param baseDir base directory + * @param fileName file name + */ + public void visit(final File baseDir, final String fileName) { + fileNames.add(fileName); + baseDirs.add(baseDir); + } + + /** + * Get value of fileName parameter for a specified index. + * + * @param index + * index + * @return value of failName parameter + */ + public String getFileName(final int index) { + return (String) fileNames.get(index); + } + + /** + * Get value of baseDir parameter for the specified index. + * + * @param index + * index + * @return value of baseDir parameter + */ + public File getBaseDir(final int index) { + return (File) baseDirs.get(index); + } + + /** + * Get count of calls to FileVisitor.visit. + * + * @return count of calls. + */ + public int size() { + return fileNames.size(); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestAllClasses.java b/src/test/java/net/sf/antcontrib/cpptasks/TestAllClasses.java new file mode 100644 index 0000000..e85fe27 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestAllClasses.java @@ -0,0 +1,63 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import junit.framework.TestSuite; +/** + * Test for abstract compiler class + * + * Override create to test concrete compiler implementions + */ +public class TestAllClasses extends TestSuite { + public static TestSuite suite() { + return new TestAllClasses("TestAllClasses"); + } + public TestAllClasses(String name) { + super(name); + addTestSuite(net.sf.antcontrib.cpptasks.TestCUtil.class); + addTestSuite(net.sf.antcontrib.cpptasks.borland.TestBorlandCCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.compiler.TestAbstractCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.compiler.TestAbstractLinker.class); + addTestSuite(net.sf.antcontrib.cpptasks.compiler.TestAbstractProcessor.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestCCTask.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestCompilerEnum.class); + addTestSuite(net.sf.antcontrib.cpptasks.compiler.TestCommandLineCompilerConfiguration.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestDependencyTable.class); + addTestSuite(net.sf.antcontrib.cpptasks.types.TestDefineArgument.class); + addTestSuite(net.sf.antcontrib.cpptasks.devstudio.TestDevStudio2005CCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.devstudio.TestDevStudioCCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.devstudio.TestDevStudioLinker.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestLinkerDef.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestTargetInfo.class); + addTestSuite(net.sf.antcontrib.cpptasks.types.TestLibrarySet.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestCompilerDef.class); + addTestSuite(net.sf.antcontrib.cpptasks.parser.TestCParser.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestGccCCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestAbstractLdLinker.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestAbstractArLibrarian.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestTargetHistoryTable.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestOutputTypeEnum.class); + addTestSuite(net.sf.antcontrib.cpptasks.compiler.TestLinkType.class); + addTestSuite(net.sf.antcontrib.cpptasks.TestLinkerEnum.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestAbstractLdLinker.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestAbstractArLibrarian.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestGccLinker.class); + addTestSuite(net.sf.antcontrib.cpptasks.gcc.TestGccLinker.class); + addTestSuite(net.sf.antcontrib.cpptasks.sun.TestForteCCCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.hp.TestaCCCompiler.class); + addTestSuite(net.sf.antcontrib.cpptasks.ibm.TestVisualAgeCCompiler.class); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestCCTask.java b/src/test/java/net/sf/antcontrib/cpptasks/TestCCTask.java new file mode 100644 index 0000000..82faae2 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestCCTask.java @@ -0,0 +1,128 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Hashtable; +import java.util.Vector; +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; + +/** + * Tests for CCTask. + * + */ +public final class TestCCTask + extends TestCase { + /** + * Constructor. + * @param name test name + * + */ + public TestCCTask(final String name) { + super(name); + } + + /** + * Test that a target with no existing object file is + * returned by getTargetsToBuildByConfiguration. + */ + public void testGetTargetsToBuildByConfiguration1() { + CompilerConfiguration config1 = new CommandLineCompilerConfiguration( + (GccCCompiler) GccCCompiler.getInstance(), "dummy", + new File[0], new File[0], new File[0], "", new String[0], + new ProcessorParam[0], true, new String[0]); + TargetInfo target1 = new TargetInfo(config1, new File[] {new File( + "src/foo.bar")} + , null, new File("foo.obj"), true); + Hashtable targets = new Hashtable(); + targets.put(target1.getOutput(), target1); + Hashtable targetsByConfig = CCTask + .getTargetsToBuildByConfiguration(targets); + Vector targetsForConfig1 = (Vector) targetsByConfig.get(config1); + assertNotNull(targetsForConfig1); + assertEquals(1, targetsForConfig1.size()); + TargetInfo targetx = (TargetInfo) targetsForConfig1.elementAt(0); + assertSame(target1, targetx); + } + + /** + * Test that a target that is up to date is not returned by + * getTargetsToBuildByConfiguration. + * + */ + public void testGetTargetsToBuildByConfiguration2() { + CompilerConfiguration config1 = new CommandLineCompilerConfiguration( + (GccCCompiler) GccCCompiler.getInstance(), "dummy", + new File[0], new File[0], new File[0], "", new String[0], + new ProcessorParam[0], false, new String[0]); + // + // target doesn't need to be rebuilt + // + TargetInfo target1 = new TargetInfo(config1, new File[] {new File( + "src/foo.bar")} + , null, new File("foo.obj"), false); + Hashtable targets = new Hashtable(); + targets.put(target1.getOutput(), target1); + // + // no targets need to be built, return a zero-length hashtable + // + Hashtable targetsByConfig = CCTask + .getTargetsToBuildByConfiguration(targets); + assertEquals(0, targetsByConfig.size()); + } + + /** + * Tests that the default value of failonerror is true. + */ + public void testGetFailOnError() { + CCTask task = new CCTask(); + boolean failOnError = task.getFailonerror(); + assertEquals(true, failOnError); + } + + /** + * Tests that setting failonerror is effective. + */ + public void testSetFailOnError() { + CCTask task = new CCTask(); + task.setFailonerror(false); + boolean failOnError = task.getFailonerror(); + assertEquals(false, failOnError); + task.setFailonerror(true); + failOnError = task.getFailonerror(); + assertEquals(true, failOnError); + } + + /** + * Test checks for the presence of antlib.xml. + * @throws IOException if stream can't be closed. + * + */ + public void testAntlibXmlPresent() throws IOException { + InputStream stream = TestCCTask.class.getClassLoader() + .getResourceAsStream("net/sf/antcontrib/cpptasks/antlib.xml"); + if (stream != null) { + stream.close(); + } + assertNotNull("antlib.xml missing", stream); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestCUtil.java b/src/test/java/net/sf/antcontrib/cpptasks/TestCUtil.java new file mode 100644 index 0000000..42b86d3 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestCUtil.java @@ -0,0 +1,153 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.IOException; + +import junit.framework.TestCase; +/** + * Tests for CUtil class + */ +public class TestCUtil extends TestCase { + public TestCUtil(String name) { + super(name); + } + public void testGetPathFromEnvironment() { + File[] files = CUtil.getPathFromEnvironment("LIB", ";"); + assertNotNull(files); + } + public void testGetRelativePath1() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, new File( + "/foo/bar/baz")); + assertEquals("baz", rel); + } + public void testGetRelativePath2() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + String rel = CUtil + .getRelativePath(canonicalBase, new File("/foo/bar/")); + assertEquals(".", rel); + } + public void testGetRelativePath3() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, + new File("/foo/bar/a")); + assertEquals("a", rel); + } + public void testGetRelativePath4() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, new File("/foo/")); + assertEquals("..", rel); + } + public void testGetRelativePath5() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, new File("/a")); + String expected = ".." + File.separator + ".." + File.separator + "a"; + assertEquals(expected, rel); + } + public void testGetRelativePath6() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, new File( + "/foo/baz/bar")); + String expected = ".." + File.separator + "baz" + File.separator + + "bar"; + assertEquals(expected, rel); + } + public void testGetRelativePath7() throws IOException { + String canonicalBase = new File("/foo/bar/").getCanonicalPath(); + // + // skip the UNC test unless running on Windows + // + String osName = System.getProperty("os.name"); + if (osName.indexOf("Windows") >= 0) { + File uncFile = new File("\\\\fred\\foo.bar"); + String uncPath; + try { + uncPath = uncFile.getCanonicalPath(); + } catch (IOException ex) { + uncPath = uncFile.toString(); + } + String rel = CUtil.getRelativePath(canonicalBase, uncFile); + assertEquals(uncPath, rel); + } + } + public void testGetRelativePath8() throws IOException { + String canonicalBase = new File("/foo/bar/something").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, + new File("/foo/bar/something.extension")); + String expected = ".." + File.separator + "something.extension"; + assertEquals(expected, rel); + } + public void testGetRelativePath9() throws IOException { + String canonicalBase = new +File("/foo/bar/something").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, + new File("/foo/bar/somethingElse")); + String expected = ".." + File.separator + "somethingElse"; + assertEquals(expected, rel); + } + public void testGetRelativePath10() throws IOException { + String canonicalBase = new +File("/foo/bar/something").getCanonicalPath(); + String rel = CUtil.getRelativePath(canonicalBase, + new File("/foo/bar/something else")); + String expected = ".." + File.separator + "something else"; + assertEquals(expected, rel); + } + public void testParsePath1() { + File[] files = CUtil.parsePath("", ";"); + assertEquals(0, files.length); + } + public void testParsePath2() { + String workingDir = System.getProperty("user.dir"); + File[] files = CUtil.parsePath(workingDir, ";"); + assertEquals(1, files.length); + File workingDirFile = new File(workingDir); + assertEquals(workingDirFile, files[0]); + } + public void testParsePath3() { + String workingDir = System.getProperty("user.dir"); + File[] files = CUtil.parsePath(workingDir + ";", ";"); + assertEquals(1, files.length); + assertEquals(new File(workingDir), files[0]); + } + public void testParsePath4() { + String workingDir = System.getProperty("user.dir"); + String javaHome = System.getProperty("java.home"); + File[] files = CUtil.parsePath(workingDir + ";" + javaHome, ";"); + assertEquals(2, files.length); + assertEquals(new File(workingDir), files[0]); + assertEquals(new File(javaHome), files[1]); + } + public void testParsePath5() { + String workingDir = System.getProperty("user.dir"); + String javaHome = System.getProperty("java.home"); + File[] files = CUtil.parsePath(workingDir + ";" + javaHome + ";", ";"); + assertEquals(2, files.length); + assertEquals(new File(workingDir), files[0]); + assertEquals(new File(javaHome), files[1]); + } + + /** + * Test of xmlAttributeEncode. + * + * See patch 1267472 and bug 1032302. + */ + public void testXmlEncode() { + assertEquals("<"boo">", CUtil.xmlAttribEncode("<\"boo\">")); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestCompilerDef.java b/src/test/java/net/sf/antcontrib/cpptasks/TestCompilerDef.java new file mode 100644 index 0000000..12e1967 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestCompilerDef.java @@ -0,0 +1,357 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.io.File; +import java.io.IOException; +import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.Compiler; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioCCompiler; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; +import net.sf.antcontrib.cpptasks.types.CompilerArgument; +import net.sf.antcontrib.cpptasks.types.ConditionalPath; +import net.sf.antcontrib.cpptasks.types.DefineArgument; +import net.sf.antcontrib.cpptasks.types.DefineSet; +import net.sf.antcontrib.cpptasks.types.IncludePath; +import net.sf.antcontrib.cpptasks.types.SystemIncludePath; +import net.sf.antcontrib.cpptasks.types.UndefineArgument; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +/** + * Tests for CompilerDef. + */ +public final class TestCompilerDef + extends TestProcessorDef { + /** + * Constructor. + * + * @param name + * test name + */ + public TestCompilerDef(final String name) { + super(name); + } + + /** + * Creates a new processor. + * + * @return new processor + */ + protected ProcessorDef create() { + return new CompilerDef(); + } + + /** + * This method tests CompilerDef.getActiveDefines. + * + * A CompilerDef is created similar to what would be created for + * + * + * + * Then getActiveDefines is called for a project without and with the + * "debug" property defined. Return value from getActiveDefines should + * contain one member + */ + public void testGetActiveDefines() { + Project project = new org.apache.tools.ant.Project(); + CompilerDef def = new CompilerDef(); + def.setProject(project); + DefineSet defset = new DefineSet(); + DefineArgument arg1 = new DefineArgument(); + arg1.setName("DEBUG"); + arg1.setIf("debug"); + defset.addDefine(arg1); + DefineArgument arg2 = new DefineArgument(); + arg2.setName("NDEBUG"); + arg2.setUnless("debug"); + defset.addDefine(arg2); + def.addConfiguredDefineset(defset); + // + // Evaluate without "debug" set + // + UndefineArgument[] activeArgs = def.getActiveDefines(); + assertEquals(1, activeArgs.length); + assertEquals("NDEBUG", activeArgs[0].getName()); + // + // Set the "debug" property + // + project.setProperty("debug", ""); + activeArgs = def.getActiveDefines(); + assertEquals(1, activeArgs.length); + assertEquals("DEBUG", activeArgs[0].getName()); + } + + /** + * This method tests CompilerDef.getActiveIncludePath. + * + * A CompilerDef is created similar to what would be created for + * + * + * + * and is evaluate for a project without and without "debug" set + */ + public void testGetActiveIncludePaths() { + Project project = new org.apache.tools.ant.Project(); + CompilerDef def = new CompilerDef(); + def.setProject(project); + ConditionalPath path = def.createIncludePath(); + path.setLocation(new File("..")); + path.setIf("debug"); + // + // Evaluate without "debug" set + // + String[] includePaths = def.getActiveIncludePaths(); + assertEquals(0, includePaths.length); + // + // Set the "debug" property + // + project.setProperty("debug", ""); + includePaths = def.getActiveIncludePaths(); + assertEquals(1, includePaths.length); + } + + /** + * Tests that setting classname to the Gcc compiler is effective. + */ + public void testGetGcc() { + CompilerDef compilerDef = (CompilerDef) create(); + compilerDef.setClassname("net.sf.antcontrib.cpptasks.gcc.GccCCompiler"); + Compiler comp = (Compiler) compilerDef.getProcessor(); + assertNotNull(comp); + assertSame(GccCCompiler.getInstance(), comp); + } + + /** + * Tests that setting classname to the MSVC compiler is effective. + */ + public void testGetMSVC() { + CompilerDef compilerDef = (CompilerDef) create(); + compilerDef + .setClassname( + "net.sf.antcontrib.cpptasks.devstudio.DevStudioCCompiler"); + Compiler comp = (Compiler) compilerDef.getProcessor(); + assertNotNull(comp); + assertSame(DevStudioCCompiler.getInstance(), comp); + } + + /** + * Tests that setting classname to an bogus class name results in a + * BuildException. + */ + public void testUnknownClass() { + CompilerDef compilerDef = (CompilerDef) create(); + try { + compilerDef + .setClassname("net.sf.antcontrib.cpptasks.bogus.BogusCompiler"); + } catch (BuildException ex) { + return; + } + fail("Exception not thrown"); + } + + /** + * Test that setting classname to a class that doesn't support Compiler + * throws a BuildException. + * + */ + public void testWrongType() { + CompilerDef compilerDef = (CompilerDef) create(); + try { + compilerDef + .setClassname("net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker"); + } catch (BuildException ex) { + return; + } + fail("Exception not thrown"); + } + + /** + * Gets the command line arguments that precede filenames. + * + * @param processor + * processor under test + * @return command line arguments + */ + protected String[] getPreArguments(final ProcessorDef processor) { + return ((CommandLineCompilerConfiguration) getConfiguration(processor)) + .getPreArguments(); + } + + /** + * Tests if a fileset enclosed in the base compiler definition is effective. + * + * @throws IOException + * if unable to create or delete a temporary file + */ + public void testExtendsFileSet() throws IOException { + super.testExtendsFileSet(File.createTempFile("cpptaskstest", ".cpp")); + } + + /** + * Tests if the rebuild attribute of the base compiler definition is + * effective. + * + */ + public void testExtendsRebuild() { + testExtendsRebuild(new CompilerDef()); + } + + /** + * Tests that compilerarg's contained in the base compiler definition are + * effective. + */ + public void testExtendsCompilerArgs() { + CompilerDef baseLinker = new CompilerDef(); + CompilerArgument linkerArg = new CompilerArgument(); + linkerArg.setValue("/base"); + baseLinker.addConfiguredCompilerArg(linkerArg); + CompilerDef extendedLinker = (CompilerDef) createExtendedProcessorDef( + baseLinker); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals(2, preArgs.length); + assertEquals("/base", preArgs[0]); + } + + /** + * Tests that defineset's contained in the base compiler definition are + * effective. + */ + public void testExtendsDefineSet() { + CompilerDef baseCompiler = new CompilerDef(); + DefineSet defSet = new DefineSet(); + DefineArgument define = new DefineArgument(); + define.setName("foo"); + define.setValue("bar"); + defSet.addDefine(define); + baseCompiler.addConfiguredDefineset(defSet); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + String[] preArgs = getPreArguments(extendedCompiler); + assertEquals(2, preArgs.length); + assertEquals("-Dfoo=bar", preArgs[1]); + } + + /** + * Tests that includepath's contained in the base compiler definition are + * effective. + */ + public void testExtendsIncludePath() { + CompilerDef baseCompiler = new CompilerDef(); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + IncludePath path = baseCompiler.createIncludePath(); + path.setPath("/tmp"); + String[] preArgs = getPreArguments(extendedCompiler); + assertEquals(2, preArgs.length); + assertEquals("-I", preArgs[1].substring(0, 2)); + } + + /** + * Tests that sysincludepath's contained in the base compiler definition are + * effective. + */ + public void testExtendsSysIncludePath() { + CompilerDef baseCompiler = new CompilerDef(); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + SystemIncludePath path = baseCompiler.createSysIncludePath(); + path.setPath("/tmp"); + String[] preArgs = getPreArguments(extendedCompiler); + assertEquals(2, preArgs.length); + assertEquals("-I", preArgs[1].substring(0, 2)); + } + + /** + * Sets the name attribute. + * + * @param compiler + * compiler under test + * @param name + * compiler name + */ + private static void setCompilerName(final CompilerDef compiler, + final String name) { + CompilerEnum compilerName = new CompilerEnum(); + compilerName.setValue(name); + compiler.setName(compilerName); + } + + /** + * Tests that the extend attribute of the base compiler definition is + * effective. + */ + public void testExtendsExceptions() { + CompilerDef baseCompiler = new CompilerDef(); + baseCompiler.setExceptions(true); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + setCompilerName(extendedCompiler, "msvc"); + String[] preArgs = getPreArguments(extendedCompiler); + assertEquals("/EHsc", preArgs[2]); + } + + /** + * Tests that the multithread attribute of the base compiler definition is + * effective. + */ + public void testExtendsMultithreaded() { + CompilerDef baseCompiler = new CompilerDef(); + baseCompiler.setMultithreaded(false); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + setCompilerName(extendedCompiler, "msvc"); + CCTask cctask = new CCTask(); + LinkType linkType = new LinkType(); + linkType.setStaticRuntime(true); + CommandLineCompilerConfiguration config = (CommandLineCompilerConfiguration) + extendedCompiler + .createConfiguration(cctask, linkType, null, null, null); + String[] preArgs = config.getPreArguments(); + assertEquals("/ML", preArgs[3]); + } + + /** + * Tests that the name attribute in the base compiler is effective. + */ + public void testExtendsName() { + CompilerDef baseCompiler = new CompilerDef(); + setCompilerName(baseCompiler, "msvc"); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + extendedCompiler.setExceptions(true); + String[] preArgs = getPreArguments(extendedCompiler); + assertEquals("/EHsc", preArgs[2]); + } + + /** + * Tests that the classname attribute in the base compiler is effective. + */ + public void testExtendsClassname() { + CompilerDef baseCompiler = new CompilerDef(); + baseCompiler + .setClassname( + "net.sf.antcontrib.cpptasks.devstudio.DevStudioCCompiler"); + CompilerDef extendedCompiler = (CompilerDef) createExtendedProcessorDef( + baseCompiler); + extendedCompiler.setExceptions(true); + String[] preArgs = getPreArguments(extendedCompiler); + assertEquals("/EHsc", preArgs[2]); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestCompilerEnum.java b/src/test/java/net/sf/antcontrib/cpptasks/TestCompilerEnum.java new file mode 100644 index 0000000..6fc72ba --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestCompilerEnum.java @@ -0,0 +1,51 @@ +/* + * + * Copyright 2002-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import junit.framework.TestCase; + +import org.apache.tools.ant.BuildException; +/** + * Tests for CompilerEnum. + */ +public class TestCompilerEnum extends TestCase { + /** + * Create instance of TestCompilerEnum. + * @param name test name. + */ + public TestCompilerEnum(final String name) { + super(name); + } + /** + * Test that "gcc" is recognized as a compiler enum. + */ + public void testCompilerEnum1() { + CompilerEnum compilerEnum = new CompilerEnum(); + compilerEnum.setValue("gcc"); + assertTrue(compilerEnum.getIndex() >= 0); + } + /** + * Test that "bogus" is not recognized as a compiler enum. + */ + public void testCompilerEnum2() { + CompilerEnum compilerEnum = new CompilerEnum(); + try { + compilerEnum.setValue("bogus"); + fail(); + } catch (BuildException ex) { + } + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestDependencyTable.java b/src/test/java/net/sf/antcontrib/cpptasks/TestDependencyTable.java new file mode 100644 index 0000000..0796353 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestDependencyTable.java @@ -0,0 +1,73 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.xml.sax.SAXException; +/** + * DependencyTable tests + * + * @author curta + */ +public class TestDependencyTable extends TestXMLConsumer { + /** + * Constructor + * + * @param testName + * test name + */ + public TestDependencyTable(String testName) { + super(testName); + } + /** + * Loads a dependency file from OpenSHORE (http://www.openshore.org) + * + * @throws IOException + */ + public void testLoadOpenshore() throws IOException, + ParserConfigurationException, SAXException { + String tmpDir = System.getProperty("java.io.tmpdir"); + try { + copyResourceToTmpDir("openshore/dependencies.xml", + "dependencies.xml"); + DependencyTable dependencies = new DependencyTable(new File(tmpDir)); + dependencies.load(); + } finally { + deleteTmpFile("dependencies.xml"); + } + } + /** + * Loads a dependency file from Xerces-C (http://xml.apache.org) + * + * @throws IOException + */ + public void testLoadXerces() throws IOException, + ParserConfigurationException, SAXException { + String tmpDir = System.getProperty("java.io.tmpdir"); + try { + copyResourceToTmpDir("xerces-c/dependencies.xml", + "dependencies.xml"); + DependencyTable dependencies = new DependencyTable(new File(tmpDir)); + dependencies.load(); + } finally { + deleteTmpFile("dependencies.xml"); + } + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestLinkerDef.java b/src/test/java/net/sf/antcontrib/cpptasks/TestLinkerDef.java new file mode 100644 index 0000000..994b068 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestLinkerDef.java @@ -0,0 +1,374 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.io.File; +import java.io.IOException; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker; +import net.sf.antcontrib.cpptasks.gcc.GccLinker; +import net.sf.antcontrib.cpptasks.types.FlexLong; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LinkerArgument; +import net.sf.antcontrib.cpptasks.types.SystemLibrarySet; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.FlexInteger; +import org.apache.tools.ant.types.Reference; + +/** + * Tests for LinkerDef class. + */ +public final class TestLinkerDef + extends TestProcessorDef { + /** + * Constructor. + * + * @param name + * test name + */ + public TestLinkerDef(final String name) { + super(name); + } + + /** + * Creates a processor. + * + * @return new linker + */ + protected ProcessorDef create() { + return new LinkerDef(); + } + + /** + * Test if setting the classname attribute to the name of the GCC linker + * results in the singleton GCC linker. + */ + public void testGetGcc() { + LinkerDef linkerDef = (LinkerDef) create(); + linkerDef.setClassname("net.sf.antcontrib.cpptasks.gcc.GccLinker"); + Linker comp = (Linker) linkerDef.getProcessor(); + assertNotNull(comp); + assertSame(GccLinker.getInstance(), comp); + } + + /** + * Test if setting the classname attribute to the name of the MSVC linker + * results in the singleton MSVC linker. + */ + public void testGetMSVC() { + LinkerDef linkerDef = (LinkerDef) create(); + linkerDef + .setClassname("net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker"); + Linker comp = (Linker) linkerDef.getProcessor(); + assertNotNull(comp); + assertSame(DevStudioLinker.getInstance(), comp); + } + + /** + * Tests if setting the classname attribute to an bogus classname results in + * a BuildException. + * + */ + public void testUnknownClass() { + LinkerDef linkerDef = (LinkerDef) create(); + try { + linkerDef + .setClassname("net.sf.antcontrib.cpptasks.bogus.BogusLinker"); + } catch (BuildException ex) { + return; + } + fail("should have thrown exception"); + } + + /** + * Tests if setting the classname to the name of a class that doesn't + * support Linker throws a BuildException. + * + */ + public void testWrongType() { + LinkerDef linkerDef = (LinkerDef) create(); + try { + linkerDef.setClassname("net.sf.antcontrib.cpptasks.CCTask"); + } catch (ClassCastException ex) { + return; + } + fail("should have thrown exception"); + } + + /** + * Gets the command line arguments that appear before the filenames. + * + * @param processor processor under test + * @return command line arguments + */ + protected String[] getPreArguments(final ProcessorDef processor) { + return ((CommandLineLinkerConfiguration) getConfiguration(processor)) + .getPreArguments(); + } + + /** + * Sets the name attribute. + * + * @param linker + * linker defintion + * @param name + * linker name + */ + private static void setLinkerName(final LinkerDef linker, + final String name) { + LinkerEnum linkerName = new LinkerEnum(); + linkerName.setValue(name); + linker.setName(linkerName); + } + + /** + * Tests that linkerarg's that appear in the base linker are effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsLinkerArgs() { + LinkerDef baseLinker = new LinkerDef(); + LinkerArgument linkerArg = new LinkerArgument(); + linkerArg.setValue("/base"); + baseLinker.addConfiguredLinkerArg(linkerArg); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals(1, preArgs.length); + assertEquals("/base", preArgs[0]); + } + + /** + * Verify linkerarg's that appear in the base linker are effective when + * creating the command line for a linker that extends it, even if the + * linker is brought in through a reference. + */ + public void testExtendsLinkerArgsViaReference() { + Project project = new Project(); + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setProject(project); + baseLinker.setId("base"); + project.addReference("base", baseLinker); + LinkerArgument linkerArg = new LinkerArgument(); + linkerArg.setValue("/base"); + baseLinker.addConfiguredLinkerArg(linkerArg); + + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + extendedLinker.setProject(project); + extendedLinker.setId("extended"); + project.addReference("extended", extendedLinker); + + LinkerDef linkerRef = new LinkerDef(); + linkerRef.setProject(project); + linkerRef.setRefid(new Reference(project, "extended")); + String[] preArgs = getPreArguments(linkerRef); + assertEquals(1, preArgs.length); + assertEquals("/base", preArgs[0]); + } + + /** + * Tests that fileset's that appear in the base linker are effective when + * creating the command line for a linker that extends it. + * @throws IOException if unable to create or delete temporary file + */ + public void testExtendsFileSet() throws IOException { + super.testExtendsFileSet(File.createTempFile("cpptaskstest", ".o")); + } + + /** + * Tests that libset's that appear in the base linker are effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsLibSet() { + LinkerDef baseLinker = new LinkerDef(); + LibrarySet libset = new LibrarySet(); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + libset.setProject(baseLinker.getProject()); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("advapi32"); + libset.setLibs(libs); + baseLinker.addLibset(libset); + CommandLineLinkerConfiguration config = (CommandLineLinkerConfiguration) + getConfiguration(extendedLinker); + String[] libnames = config.getLibraryNames(); + assertEquals(1, libnames.length); + assertEquals("advapi32", libnames[0]); + } + + /** + * Tests that syslibset's that appear in the base linker are effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsSysLibSet() { + LinkerDef baseLinker = new LinkerDef(); + SystemLibrarySet libset = new SystemLibrarySet(); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + libset.setProject(baseLinker.getProject()); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("advapi32"); + libset.setLibs(libs); + baseLinker.addSyslibset(libset); + CommandLineLinkerConfiguration config = (CommandLineLinkerConfiguration) + getConfiguration(extendedLinker); + String[] libnames = config.getLibraryNames(); + assertEquals(1, libnames.length); + assertEquals("advapi32", libnames[0]); + } + + /** + * Tests that the base attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsBase() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setBase(new FlexLong("10000")); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + setLinkerName(extendedLinker, "msvc"); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:NO", preArgs[2]); + assertEquals("/BASE:0x2710", preArgs[3]); + } + + /** + * Tests that the stack attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsStack() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setStack(new FlexInteger("10000")); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + setLinkerName(extendedLinker, "msvc"); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:NO", preArgs[2]); + assertEquals("/STACK:0x2710", preArgs[3]); + } + + /** + * Tests that the entry attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsEntry() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setEntry("foo"); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("-e", preArgs[0]); + assertEquals("foo", preArgs[1]); + } + + /** + * Tests that the fixed attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsFixed() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setFixed(true); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + setLinkerName(extendedLinker, "msvc"); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:NO", preArgs[2]); + assertEquals("/FIXED", preArgs[3]); + } + + /** + * Tests that the incremental attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsIncremental() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setIncremental(true); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + setLinkerName(extendedLinker, "msvc"); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:YES", preArgs[2]); + } + + /** + * Tests that the map attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsMap() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker.setMap(true); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + setLinkerName(extendedLinker, "msvc"); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:NO", preArgs[2]); + assertEquals("/MAP", preArgs[3]); + } + + /** + * Tests that the rebuild attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsRebuild() { + testExtendsRebuild(new LinkerDef()); + } + + /** + * Tests that the name attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsName() { + LinkerDef baseLinker = new LinkerDef(); + setLinkerName(baseLinker, "msvc"); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + extendedLinker.setBase(new FlexLong("10000")); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:NO", preArgs[2]); + assertEquals("/BASE:0x2710", preArgs[3]); + } + + /** + * Tests that the classname attribute in the base linker is effective when + * creating the command line for a linker that extends it. + */ + public void testExtendsClassname() { + LinkerDef baseLinker = new LinkerDef(); + baseLinker + .setClassname("net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker"); + LinkerDef extendedLinker = (LinkerDef) createExtendedProcessorDef( + baseLinker); + extendedLinker.setBase(new FlexLong("10000")); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("/NOLOGO", preArgs[0]); + assertEquals("/SUBSYSTEM:WINDOWS", preArgs[1]); + assertEquals("/INCREMENTAL:NO", preArgs[2]); + assertEquals("/BASE:0x2710", preArgs[3]); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestLinkerEnum.java b/src/test/java/net/sf/antcontrib/cpptasks/TestLinkerEnum.java new file mode 100644 index 0000000..2726750 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestLinkerEnum.java @@ -0,0 +1,40 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import junit.framework.TestCase; +/** + * + * Tests for LinkerEnum + * + * @author CurtA + */ +public class TestLinkerEnum extends TestCase { + /** + * @param name test case name + */ + public TestLinkerEnum(String name) { + super(name); + } + /** + * Test checks that enumeration contains value g++ + * + * See patch [ 676276 ] Enhanced support for Mac OS X + */ + public void testContainsValueGpp() { + assertTrue(new LinkerEnum().containsValue("g++")); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestOutputTypeEnum.java b/src/test/java/net/sf/antcontrib/cpptasks/TestOutputTypeEnum.java new file mode 100644 index 0000000..61bb2b7 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestOutputTypeEnum.java @@ -0,0 +1,39 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import junit.framework.TestCase; +/** + * @author CurtA + */ +public class TestOutputTypeEnum extends TestCase { + /** + * Default constructor + * + * @see junit.framework.TestCase#TestCase(String) + */ + public TestOutputTypeEnum(String name) { + super(name); + } + /** + * Test checks that output type enum contains "plugin" + * + * See patch [ 676276 ] Enhanced support for Mac OS X + */ + public void testContainsValuePlugin() { + assertTrue(new OutputTypeEnum().containsValue("plugin")); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestProcessorDef.java b/src/test/java/net/sf/antcontrib/cpptasks/TestProcessorDef.java new file mode 100644 index 0000000..c4e2905 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestProcessorDef.java @@ -0,0 +1,278 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks; + +import java.io.File; +import java.io.IOException; +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Reference; + +/** + * Tests for ProcessorDef. + */ +public abstract class TestProcessorDef + extends TestCase { + + /** + * Constructor. + * + * @param name + * test name + */ + public TestProcessorDef(final String name) { + super(name); + } + + /** + * Creates a new processor definition. + * + * @return created processor definition + */ + protected abstract ProcessorDef create(); + + /** + * Tests that isActive returns true when "if" references a set property. + */ + public final void testIsActive2() { + ProcessorDef arg = create(); + Project project = new Project(); + project.setProperty("cond", ""); + arg.setProject(project); + arg.setIf("cond"); + assertTrue(arg.isActive()); + } + + /** + * Tests that isActive returns false when "if" references an unset property. + */ + public final void testIsActive3() { + ProcessorDef arg = create(); + arg.setProject(new Project()); + arg.setIf("cond"); + assertTrue(!arg.isActive()); + } + + /** + * Tests that evaluating isActive when "if" refernces a property with the + * value "false" throws an exception to warn of a suspicious value. + * + */ + public final void testIsActive4() { + ProcessorDef arg = create(); + Project project = new Project(); + project.setProperty("cond", "false"); + arg.setProject(project); + arg.setIf("cond"); + try { + boolean isActive = arg.isActive(); + } catch (BuildException ex) { + return; + } + fail("Should throw exception for suspicious value"); + } + + /** + * Tests that isActive returns false when "unless" references a set + * property. + */ + public final void testIsActive5() { + ProcessorDef arg = create(); + Project project = new Project(); + project.setProperty("cond", ""); + arg.setProject(project); + arg.setUnless("cond"); + assertTrue(!arg.isActive()); + } + + /** + * Tests that isActive returns true when "unless" references an unset + * property. + */ + public final void testIsActive6() { + ProcessorDef arg = create(); + arg.setProject(new Project()); + arg.setUnless("cond"); + assertTrue(arg.isActive()); + } + + /** + * Tests that evaluating isActive when "unless" references a property with + * the value "false" throws an exception to warn of a suspicious value. + * + */ + public final void testIsActive7() { + ProcessorDef arg = create(); + Project project = new Project(); + project.setProperty("cond", "false"); + arg.setProject(project); + arg.setUnless("cond"); + try { + boolean isActive = arg.isActive(); + } catch (BuildException ex) { + return; + } + fail("Should throw exception for suspicious value"); + } + + /** + * Tests if a processor is active when both "if" and "unless" are specified + * and the associated properties are set. + * + */ + public final void testIsActive8() { + ProcessorDef arg = create(); + Project project = new Project(); + project.setProperty("cond", ""); + arg.setProject(project); + arg.setIf("cond"); + arg.setUnless("cond"); + assertTrue(!arg.isActive()); + } + + /** + * Creates a processor initialized to be an extension of the base processor. + * + * @param baseProcessor + * base processor + * @return extending processor + */ + protected final ProcessorDef createExtendedProcessorDef( + final ProcessorDef baseProcessor) { + Project project = new Project(); + baseProcessor.setProject(project); + baseProcessor.setId("base"); + project.addReference("base", baseProcessor); + ProcessorDef extendedLinker = create(); + extendedLinker.setProject(project); + extendedLinker.setExtends(new Reference("base")); + return extendedLinker; + } + + /** + * Gets the processor configuration. + * + * @param extendedProcessor + * processor under test + * @return configuration + */ + protected final ProcessorConfiguration getConfiguration( + final ProcessorDef extendedProcessor) { + CCTask cctask = new CCTask(); + LinkType linkType = new LinkType(); + return extendedProcessor.createConfiguration(cctask, + linkType, + null, + null, + null); + } + + /** + * Gets command line arguments that precede filenames. + * + * @param processor + * processor under test + * @return array of command line parameters + */ + protected abstract String[] getPreArguments(final ProcessorDef processor); + + /** + * Tests that a fileset in the base processor is effective when evaluating + * the files included in an extending processor. + * + * @param tempFile + * temporary file + * @throws IOException + * if unable to delete file + */ + protected final void testExtendsFileSet(final File tempFile) throws + IOException { + ProcessorDef baseLinker = create(); + ConditionalFileSet fileSet = new ConditionalFileSet(); + ProcessorDef extendedLinker = createExtendedProcessorDef(baseLinker); + fileSet.setProject(baseLinker.getProject()); + fileSet.setDir(new File(tempFile.getParent())); + fileSet.setIncludes(tempFile.getName()); + baseLinker.addFileset(fileSet); + MockFileCollector collector = new MockFileCollector(); + extendedLinker.visitFiles(collector); + tempFile.delete(); + assertEquals(1, collector.size()); + } + + /** + * Tests that the if attribute in the base processor is effective when + * evaluating if an extending processor is active. + */ + public final void testExtendsIf() { + ProcessorDef baseLinker = create(); + baseLinker.setIf("bogus"); + ProcessorDef extendedLinker = createExtendedProcessorDef(baseLinker); + boolean isActive = extendedLinker.isActive(); + assertEquals(false, isActive); + baseLinker.getProject().setProperty("bogus", ""); + isActive = extendedLinker.isActive(); + assertEquals(true, isActive); + } + + /** + * Tests that the unless attribute in the base processor is effective when + * evaluating if an extending processor is active. + */ + public final void testExtendsUnless() { + ProcessorDef baseLinker = create(); + baseLinker.setUnless("bogus"); + ProcessorDef extendedLinker = createExtendedProcessorDef(baseLinker); + boolean isActive = extendedLinker.isActive(); + assertEquals(true, isActive); + baseLinker.getProject().setProperty("bogus", ""); + isActive = extendedLinker.isActive(); + assertEquals(false, isActive); + } + + /** + * Tests that the debug attribute in the base processor is effective when + * creating the command line for a processor that extends it. + */ + public final void testExtendsDebug() { + ProcessorDef baseLinker = create(); + baseLinker.setDebug(true); + ProcessorDef extendedLinker = createExtendedProcessorDef(baseLinker); + String[] preArgs = getPreArguments(extendedLinker); + assertEquals("-g", preArgs[preArgs.length - 1]); + } + + /** + * Tests that the rebuild attribute in the base processor is effective when + * creating the command line for a processor that extends it. + * + * @param baseProcessor + * processor under test + */ + protected final void testExtendsRebuild( + final ProcessorDef baseProcessor) { + baseProcessor.setRebuild(true); + ProcessorDef extendedLinker = createExtendedProcessorDef(baseProcessor); + ProcessorConfiguration config = getConfiguration(extendedLinker); + boolean rebuild = config.getRebuild(); + assertEquals(true, rebuild); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestTargetHistoryTable.java b/src/test/java/net/sf/antcontrib/cpptasks/TestTargetHistoryTable.java new file mode 100644 index 0000000..b105eb6 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestTargetHistoryTable.java @@ -0,0 +1,141 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; +import net.sf.antcontrib.cpptasks.VersionInfo; +/** + * Tests for TargetHistoryTable + * + * @author CurtA + */ +public class TestTargetHistoryTable extends TestXMLConsumer { + public static class MockProcessorConfiguration + implements + ProcessorConfiguration { + public MockProcessorConfiguration() { + } + public int bid(String fileName) { + return 100; + } + public String getIdentifier() { + return "Mock Configuration"; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + return new String[] { baseName }; + } + public ProcessorParam[] getParams() { + return new ProcessorParam[0]; + } + public boolean getRebuild() { + return false; + } + } + /** + * Constructor + * + * @param name + * test case name + * @see junit.framework.TestCase#TestCase(String) + */ + public TestTargetHistoryTable(String name) { + super(name); + } + /** + * Tests loading a stock history file + * + * @throws IOException + */ + public void testLoadOpenshore() throws IOException { + try { + copyResourceToTmpDir("openshore/history.xml", "history.xml"); + CCTask task = new CCTask(); + String tmpDir = System.getProperty("java.io.tmpdir"); + TargetHistoryTable history = new TargetHistoryTable(task, new File( + tmpDir)); + } finally { + deleteTmpFile("history.xml"); + } + } + /** + * Tests loading a stock history file + * + * @throws IOException + */ + public void testLoadXerces() throws IOException { + try { + copyResourceToTmpDir("xerces-c/history.xml", "history.xml"); + CCTask task = new CCTask(); + String tmpDir = System.getProperty("java.io.tmpdir"); + TargetHistoryTable history = new TargetHistoryTable(task, new File( + tmpDir)); + } finally { + deleteTmpFile("history.xml"); + } + } + /** + * Tests for bug fixed by patch [ 650397 ] Fix: Needless rebuilds on Unix + * + * @throws IOException + */ + public void testUpdateTimeResolution() throws IOException { + File compiledFile = null; + try { + // + // delete any history file that might exist + // in the test output directory + String tempDir = System.getProperty("java.io.tmpdir"); + File historyFile = new File(tempDir, "history.xml"); + if (historyFile.exists()) { + historyFile.delete(); + } + TargetHistoryTable table = new TargetHistoryTable(null, new File( + tempDir)); + // + // create a dummy compiled unit + // + compiledFile = new File(tempDir, "dummy.o"); + FileOutputStream compiledStream = new FileOutputStream(compiledFile); + compiledStream.close(); + // + // lastModified times can be slightly less than + // task start time due to file system resolution. + // Mimic this by slightly incrementing the last modification time. + // + long startTime = compiledFile.lastModified() + 1; + // + // update the table + // + table.update(new MockProcessorConfiguration(), + new String[]{"dummy.o"}, null); + // + // commit. If "compiled" file was judged to be + // valid we should have a history file. + // + table.commit(); + assertTrue("History file was not created", historyFile.exists()); + assertTrue("History file was empty", historyFile.length() > 10); + } finally { + if (compiledFile != null && compiledFile.exists()) { + compiledFile.delete(); + } + } + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestTargetInfo.java b/src/test/java/net/sf/antcontrib/cpptasks/TestTargetInfo.java new file mode 100644 index 0000000..5851805 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestTargetInfo.java @@ -0,0 +1,134 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor; +import org.apache.tools.ant.BuildException; +import net.sf.antcontrib.cpptasks.VersionInfo; + + +/** + * A description of a file built or to be built + */ +public class TestTargetInfo extends TestCase { + private class DummyConfiguration implements CompilerConfiguration { + public int bid(String filename) { + return 1; + } + public void close() { + } + public void compile(CCTask task, File workingDir, String[] source, + boolean relentless, ProgressMonitor monitor) + throws BuildException { + throw new BuildException("Not implemented"); + } + public CompilerConfiguration[] createPrecompileConfigurations( + File file, String[] exceptFiles) { + return null; + } + public String getIdentifier() { + return "dummy"; + } + public String[] getIncludeDirectories() { + return new String[0]; + } + public String getIncludePathIdentifier() { + return "dummyIncludePath"; + } + public String[] getOutputFileNames(String inputFile, VersionInfo versionInfo) { + return new String[0]; + } + public CompilerParam getParam(String name) { + return null; + } + public ProcessorParam[] getParams() { + return new ProcessorParam[0]; + } + public boolean getRebuild() { + return false; + } + public boolean isPrecompileGeneration() { + return true; + } + public DependencyInfo parseIncludes(CCTask task, File baseDir, File file) { + return null; + } + } + public TestTargetInfo(String name) { + super(name); + } + public void testConstructorNullConfig() { + try { + new TargetInfo(null, new File[]{new File("")}, null, new File(""), + false); + fail("Didn't throw exception"); + } catch (NullPointerException ex) { + } + } + public void testConstructorNullOutput() { + CompilerConfiguration config = new DummyConfiguration(); + try { + new TargetInfo(config, new File[]{new File("")}, null, null, false); + fail("Didn't throw exception"); + } catch (NullPointerException ex) { + } + } + public void testConstructorNullSource() { + CompilerConfiguration config = new DummyConfiguration(); + try { + new TargetInfo(config, null, null, new File(""), false); + fail("Didn't throw exception"); + } catch (NullPointerException ex) { + } + } + public void testGetRebuild() { + CompilerConfiguration config = new DummyConfiguration(); + TargetInfo targetInfo = new TargetInfo(config, new File[]{new File( + "FoO.BaR")}, null, new File("foo.o"), false); + assertEquals(false, targetInfo.getRebuild()); + targetInfo = new TargetInfo(config, new File[]{new File("FoO.BaR")}, + null, new File("foo.o"), true); + assertEquals(true, targetInfo.getRebuild()); + } + public void testGetSource() { + CompilerConfiguration config = new DummyConfiguration(); + TargetInfo targetInfo = new TargetInfo(config, new File[]{new File( + "FoO.BaR")}, null, new File("foo.o"), false); + String source = targetInfo.getSources()[0].getName(); + assertEquals(source, "FoO.BaR"); + } + public void testHasSameSource() { + CompilerConfiguration config = new DummyConfiguration(); + TargetInfo targetInfo = new TargetInfo(config, new File[]{new File( + "foo.bar")}, null, new File("foo.o"), false); + boolean hasSame = targetInfo.getSources()[0] + .equals(new File("foo.bar")); + assertTrue(hasSame); + hasSame = targetInfo.getSources()[0].equals(new File("boo.far")); + assertEquals(hasSame, false); + } + public void testMustRebuild() { + CompilerConfiguration config = new DummyConfiguration(); + TargetInfo targetInfo = new TargetInfo(config, new File[]{new File( + "FoO.BaR")}, null, new File("foo.o"), false); + assertEquals(false, targetInfo.getRebuild()); + targetInfo.mustRebuild(); + assertEquals(true, targetInfo.getRebuild()); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/TestXMLConsumer.java b/src/test/java/net/sf/antcontrib/cpptasks/TestXMLConsumer.java new file mode 100644 index 0000000..5e7b007 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/TestXMLConsumer.java @@ -0,0 +1,96 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import junit.framework.TestCase; +/** + * Base class for tests on classes that consume or public XML documents. + * + * @author Curt Arnold + * + */ +public abstract class TestXMLConsumer extends TestCase { + /** + * copies a resource to a temporary directory. + * + * @param resourceName + * resouce name, such as "files/openshore/history.xml". + * @param tmpFile name for temporary file created in /tmp or similar. + */ + public static final void copyResourceToTmpDir(String resourceName, + String tmpFile) throws IOException { + String tmpDir = System.getProperty("java.io.tmpdir"); + // + // attempt to get resource from jar + // (should succeed unless testing in IDE) + InputStream src = null; + if (TestTargetHistoryTable.class.getClassLoader().getResource( + resourceName) != null) { + src = TestTargetHistoryTable.class.getClassLoader() + .getResourceAsStream(resourceName); + } + // + // if not found, try to find it relative to the current directory + // + if (src == null) { + src = new FileInputStream(resourceName); + } + assertNotNull("Could not locate resource " + resourceName, src); + try { + File destFile = new File(tmpDir, tmpFile); + FileOutputStream dest = new FileOutputStream(destFile); + try { + int bytesRead = 0; + byte[] buffer = new byte[4096]; + do { + bytesRead = src.read(buffer); + if (bytesRead > 0) { + dest.write(buffer, 0, bytesRead); + } + } while (bytesRead == buffer.length); + } finally { + dest.close(); + } + } finally { + src.close(); + } + } + /** + * Deletes a file, if it exists, from the user's temporary directory. + * + * @param tmpName + * file name, may not be null + */ + public static void deleteTmpFile(String tmpName) throws IOException { + String tmpDir = System.getProperty("java.io.tmpdir"); + File tmpFile = new File(tmpDir, tmpName); + if (tmpFile.exists()) { + tmpFile.delete(); + } + } + /** + * @param testName + */ + protected TestXMLConsumer(final String testName) { + super(testName); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/borland/TestBorlandCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/borland/TestBorlandCCompiler.java new file mode 100644 index 0000000..ddafc5e --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/borland/TestBorlandCCompiler.java @@ -0,0 +1,37 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.borland; +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +import net.sf.antcontrib.cpptasks.compiler.TestAbstractCompiler; +/** + * Borland C++ Compiler adapter tests + * + * Override create to test concrete compiler implementions + */ +public class TestBorlandCCompiler extends TestAbstractCompiler { + public TestBorlandCCompiler(String name) { + super(name); + } + protected AbstractProcessor create() { + return BorlandCCompiler.getInstance(); + } + protected String getObjectExtension() { + return ".obj"; + } + public void testGetIdentfier() { + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractCompiler.java new file mode 100644 index 0000000..5a1e66b --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractCompiler.java @@ -0,0 +1,85 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CompilerDef; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +import net.sf.antcontrib.cpptasks.VersionInfo; + +import org.apache.tools.ant.BuildException; +/** + * Test for abstract compiler class + * + * Override create to test concrete compiler implementions + */ +public class TestAbstractCompiler extends TestAbstractProcessor { + private class DummyAbstractCompiler extends AbstractCompiler { + public DummyAbstractCompiler() { + super(new String[]{".cpp", ".c"}, + new String[]{".hpp", ".h", ".inl"}, ".o"); + } + public void compile(CCTask task, File[] srcfile, File[] outputfile, + CompilerConfiguration config) throws BuildException { + throw new BuildException("Not implemented"); + } + public CompilerConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef[] def1, CompilerDef def2, + net.sf.antcontrib.cpptasks.TargetDef targetPlatform, + VersionInfo versionInfo) { + return null; + } + public Parser createParser(File file) { + return new CParser(); + } + public String getIdentifier() { + return "dummy"; + } + public Linker getLinker(LinkType type) { + return null; + } + } + public TestAbstractCompiler(String name) { + super(name); + } + protected AbstractProcessor create() { + return new DummyAbstractCompiler(); + } + protected String getObjectExtension() { + return ".o"; + } + public void testCanParseTlb() { + AbstractCompiler compiler = (AbstractCompiler) create(); + assertEquals(false, compiler.canParse(new File("sample.tlb"))); + } + public void testGetOutputFileName1() { + AbstractProcessor compiler = create(); + String[] output = compiler.getOutputFileNames("c:/foo\\bar\\hello.c", null); + assertEquals("hello" + getObjectExtension(), output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar/hello.c", null); + assertEquals("hello" + getObjectExtension(), output[0]); + output = compiler.getOutputFileNames("hello.c", null); + assertEquals("hello" + getObjectExtension(), output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar\\hello.h", null); + assertEquals(0, output.length); + output = compiler.getOutputFileNames("c:/foo\\bar/hello.h", null); + assertEquals(0, output.length); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractLinker.java b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractLinker.java new file mode 100644 index 0000000..b444a0a --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractLinker.java @@ -0,0 +1,89 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.LinkerDef; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +import net.sf.antcontrib.cpptasks.TargetDef; +import net.sf.antcontrib.cpptasks.VersionInfo; + +/** + * Test for abstract compiler class + * + * Override create to test concrete compiler implementions + */ +public class TestAbstractLinker extends TestAbstractProcessor { + private class DummyAbstractLinker extends AbstractLinker { + public DummyAbstractLinker() { + super(new String[]{".obj", ".lib"}, new String[]{".map", ".exp"}); + } + public LinkerConfiguration createConfiguration(final CCTask task, + final LinkType linkType, + final ProcessorDef[] def1, + final LinkerDef def2, + final TargetDef targetPlatform, + final VersionInfo versionInfo) { + return null; + } + public String getIdentifier() { + return "dummy"; + } + public File[] getLibraryPath() { + return new File[0]; + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + return libnames; + } + public Linker getLinker(LinkType type) { + return null; + } + public String[] getOutputFileNames(String sourceFile, VersionInfo versionInfo) { + return new String[0]; + } + public String[][] getRuntimeLibraries(boolean debug, + boolean multithreaded, boolean staticLink) { + return new String[2][0]; + } + public boolean isCaseSensitive() { + return true; + } + } + public TestAbstractLinker(String name) { + super(name); + } + protected AbstractProcessor create() { + return new DummyAbstractLinker(); + } + public void testBid() { + AbstractProcessor compiler = create(); + int bid = compiler.bid("c:/foo\\bar\\hello.obj"); + assertEquals(100, bid); + bid = compiler.bid("c:/foo\\bar/hello.lib"); + assertEquals(100, bid); + bid = compiler.bid("c:/foo\\bar\\hello.map"); + assertEquals(0, bid); + bid = compiler.bid("c:/foo\\bar/hello.map"); + assertEquals(0, bid); + bid = compiler.bid("c:/foo\\bar/hello.c"); + assertEquals(1, bid); + bid = compiler.bid("c:/foo\\bar/hello.cpp"); + assertEquals(1, bid); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractProcessor.java b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractProcessor.java new file mode 100644 index 0000000..f2c04a3 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestAbstractProcessor.java @@ -0,0 +1,80 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.ProcessorDef; +import net.sf.antcontrib.cpptasks.VersionInfo; +/** + * Test for abstract compiler class + * + * Override create to test concrete compiler implementions + */ +public class TestAbstractProcessor extends TestCase { + private class DummyAbstractProcessor extends AbstractProcessor { + public DummyAbstractProcessor() { + super(new String[]{".cpp", ".c"}, + new String[]{".hpp", ".h", ".inl"}); + } + public ProcessorConfiguration createConfiguration(CCTask task, + LinkType linkType, ProcessorDef[] defaultProvider, + ProcessorDef specificProvider, + net.sf.antcontrib.cpptasks.TargetDef targetPlatform, + VersionInfo versionInfo) { + return null; + } + public String getIdentifier() { + return "dummy"; + } + public Linker getLinker(LinkType type) { + return null; + } + public String[] getOutputFileNames(String sourceFile, VersionInfo versionInfo) { + return new String[0]; + } + public String[][] getRuntimeLibraries(boolean debug, + boolean multithreaded, boolean staticLink) { + return new String[2][0]; + } + } + public TestAbstractProcessor(String name) { + super(name); + } + protected AbstractProcessor create() { + return new DummyAbstractProcessor(); + } + public void testBid() { + AbstractProcessor compiler = create(); + int bid = compiler.bid("c:/foo\\bar\\hello.c"); + assertEquals(100, bid); + bid = compiler.bid("c:/foo\\bar/hello.c"); + assertEquals(100, bid); + bid = compiler.bid("c:/foo\\bar\\hello.h"); + assertEquals(1, bid); + bid = compiler.bid("c:/foo\\bar/hello.h"); + assertEquals(1, bid); + bid = compiler.bid("c:/foo\\bar/hello.pas"); + assertEquals(0, bid); + bid = compiler.bid("c:/foo\\bar/hello.java"); + assertEquals(0, bid); + } + public void testGetIdentfier() { + AbstractProcessor compiler = create(); + String id = compiler.getIdentifier(); + assertEquals("dummy", id); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCommandLineCompilerConfiguration.java b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCommandLineCompilerConfiguration.java new file mode 100644 index 0000000..a22fa0d --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCommandLineCompilerConfiguration.java @@ -0,0 +1,59 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import java.io.File; + +import net.sf.antcontrib.cpptasks.ProcessorParam; +import net.sf.antcontrib.cpptasks.gcc.GccCCompiler; +/** + */ +public class TestCommandLineCompilerConfiguration + extends + TestCompilerConfiguration { + private final CommandLineCompiler compiler; + private final String compilerId; + public TestCommandLineCompilerConfiguration(String name) { + super(name); + compiler = (GccCCompiler) GccCCompiler.getInstance(); + compilerId = compiler.getIdentifier(); + } + protected CompilerConfiguration create() { + return new CommandLineCompilerConfiguration(compiler, "dummy", + new File[0], new File[0], new File[0], "", + new String[]{"/Id:/gcc"}, new ProcessorParam[0], false, + new String[0]); + } + public void testConstructorNullCompiler() { + try { + new CommandLineCompilerConfiguration(null, "dummy", new File[0], + new File[0], new File[0], "", new String[0], + new ProcessorParam[0], false, new String[0]); + fail("Should throw exception for null compiler"); + } catch (NullPointerException ex) { + } + } + public void testGetIdentifier() { + CompilerConfiguration config = create(); + String id = config.getIdentifier(); + assertEquals("dummy", id); + } + public void testToString() { + CompilerConfiguration config = create(); + String toString = config.toString(); + assertEquals("dummy", toString); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCompilerConfiguration.java b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCompilerConfiguration.java new file mode 100644 index 0000000..a928ae4 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestCompilerConfiguration.java @@ -0,0 +1,68 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import junit.framework.TestCase; +/** + */ +public abstract class TestCompilerConfiguration extends TestCase { + public TestCompilerConfiguration(String name) { + super(name); + } + protected abstract CompilerConfiguration create(); + public String getObjectFileExtension() { + return ".o"; + } + public void testBid() { + CompilerConfiguration compiler = create(); + int bid = compiler.bid("c:/foo\\bar\\hello.c"); + assertEquals(100, bid); + bid = compiler.bid("c:/foo\\bar/hello.c"); + assertEquals(100, bid); + bid = compiler.bid("c:/foo\\bar\\hello.h"); + assertEquals(1, bid); + bid = compiler.bid("c:/foo\\bar/hello.h"); + assertEquals(1, bid); + bid = compiler.bid("c:/foo\\bar/hello.pas"); + assertEquals(0, bid); + bid = compiler.bid("c:/foo\\bar/hello.java"); + assertEquals(0, bid); + } + public void testGetOutputFileName1() { + CompilerConfiguration compiler = create(); + String input = "c:/foo\\bar\\hello.c"; + // + // may cause IllegalStateException since + // setPlatformInfo has not been called + try { + String[] output = compiler.getOutputFileNames(input, null); + } catch (java.lang.IllegalStateException ex) { + } + } + public void testGetOutputFileName2() { + CompilerConfiguration compiler = create(); + String[] output = compiler.getOutputFileNames("c:/foo\\bar\\hello.c", null); + assertEquals("hello" + getObjectFileExtension(), output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar/hello.c", null); + assertEquals("hello" + getObjectFileExtension(), output[0]); + output = compiler.getOutputFileNames("hello.c", null); + assertEquals("hello" + getObjectFileExtension(), output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar\\hello.h", null); + assertEquals(0, output.length); + output = compiler.getOutputFileNames("c:/foo\\bar/hello.h", null); + assertEquals(0, output.length); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestLinkType.java b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestLinkType.java new file mode 100644 index 0000000..a7e3a45 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/compiler/TestLinkType.java @@ -0,0 +1,59 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.compiler; +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.OutputTypeEnum; +/** + * Tests for LinkType + * + * @author CurtA + */ +public class TestLinkType extends TestCase { + /** + * Constructor + * + * @param name + * test case name + */ + public TestLinkType(String name) { + super(name); + } + /** + * Tests if isPluginModule returns true when set to plugin output type + * + * See patch [ 676276 ] Enhanced support for Mac OS X + */ + public void testIsPluginFalse() { + LinkType type = new LinkType(); + OutputTypeEnum pluginType = new OutputTypeEnum(); + pluginType.setValue("executable"); + type.setOutputType(pluginType); + assertTrue(!type.isPluginModule()); + } + /** + * Tests if isPluginModule returns true when set to plugin output type + * + * See patch [ 676276 ] Enhanced support for Mac OS X + */ + public void testIsPluginTrue() { + LinkType type = new LinkType(); + OutputTypeEnum pluginType = new OutputTypeEnum(); + pluginType.setValue("plugin"); + type.setOutputType(pluginType); + assertTrue(type.isPluginModule()); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudio2005CCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudio2005CCompiler.java new file mode 100644 index 0000000..dccb986 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudio2005CCompiler.java @@ -0,0 +1,41 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.util.Vector; + +import junit.framework.TestCase; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +/** + * Test Microsoft C/C++ compiler adapter + * + */ +public class TestDevStudio2005CCompiler extends TestCase { + public TestDevStudio2005CCompiler(String name) { + super(name); + } + public void testDebug() { + DevStudio2005CCompiler compiler = DevStudio2005CCompiler.getInstance(); + Vector args = new Vector(); + compiler.addDebugSwitch(args); + assertEquals(4, args.size()); + assertEquals("/Zi", args.elementAt(0)); + assertEquals("/Od", args.elementAt(1)); + assertEquals("/RTC1", args.elementAt(2)); + assertEquals("/D_DEBUG", args.elementAt(3)); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioCCompiler.java new file mode 100644 index 0000000..eeeec14 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioCCompiler.java @@ -0,0 +1,41 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import java.util.Vector; + +import junit.framework.TestCase; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +/** + * Test Microsoft C/C++ compiler adapter + * + */ +public class TestDevStudioCCompiler extends TestCase { + public TestDevStudioCCompiler(String name) { + super(name); + } + public void testDebug() { + DevStudioCCompiler compiler = DevStudioCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addDebugSwitch(args); + assertEquals(4, args.size()); + assertEquals("/Zi", args.elementAt(0)); + assertEquals("/Od", args.elementAt(1)); + assertEquals("/GZ", args.elementAt(2)); + assertEquals("/D_DEBUG", args.elementAt(3)); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioLinker.java b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioLinker.java new file mode 100644 index 0000000..7fdaabe --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestDevStudioLinker.java @@ -0,0 +1,44 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +import net.sf.antcontrib.cpptasks.compiler.TestAbstractLinker; +import org.apache.tools.ant.taskdefs.condition.Os; +/** + * Test for Microsoft Developer Studio linker + * + * Override create to test concrete compiler implementions + */ +public class TestDevStudioLinker extends TestAbstractLinker { + public TestDevStudioLinker(String name) { + super(name); + } + protected AbstractProcessor create() { + return DevStudioLinker.getInstance(); + } + public void testGetIdentfier() { + if (!Os.isFamily("windows")) { + return; + } + AbstractProcessor compiler = create(); + String id = compiler.getIdentifier(); + boolean hasMSLinker = ((id.indexOf("Microsoft") >= 0) && (id + .indexOf("Linker") >= 0)) + || id.indexOf("link") >= 0; + assertTrue(hasMSLinker); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestInstalledDevStudioLinker.java b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestInstalledDevStudioLinker.java new file mode 100644 index 0000000..07f1339 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/devstudio/TestInstalledDevStudioLinker.java @@ -0,0 +1,60 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.devstudio; + +import java.io.File; + + +/** + * Test for Microsoft Developer Studio linker + * + * Override create to test concrete compiler implementions + */ +public class TestInstalledDevStudioLinker extends TestDevStudioLinker +{ + public TestInstalledDevStudioLinker(String name) { + super(name); + } + + public void testGetLibraryPath() { + File[] libpath = DevStudioLinker.getInstance().getLibraryPath(); + // + // unless you tweak the library path + // it should have more thean three entries + assertTrue(libpath.length >= 2); + // + // check if these files can be found + // + String[] libnames = new String[] { "kernel32.lib", + "advapi32.lib", "msvcrt.lib", "mfc42.lib", "mfc70.lib" }; + boolean[] libfound = new boolean[libnames.length]; + for (int i = 0; i < libpath.length; i++) { + for (int j = 0; j < libnames.length; j++) { + File libfile = new File(libpath[i], libnames[j]); + if (libfile.exists()) { + libfound[j] = true; + } + } + } + assertTrue("kernel32 not found", libfound[0]); + assertTrue("advapi32 not found", libfound[1]); + assertTrue("msvcrt not found", libfound[2]); + if(!(libfound[3] || libfound[4])) { + fail("mfc42.lib or mfc70.lib not found"); + } + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractArLibrarian.java b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractArLibrarian.java new file mode 100644 index 0000000..0fc8449 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractArLibrarian.java @@ -0,0 +1,79 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +import net.sf.antcontrib.cpptasks.compiler.TestAbstractLinker; +/** + * Tests for classes that derive from AbstractArLibrarian + * + * @author CurtA + */ +public class TestAbstractArLibrarian extends TestAbstractLinker { + /** + * Constructor + * + * @param name + * test name + * @see junit.framework.TestCase#TestCase(String) + */ + public TestAbstractArLibrarian(String name) { + super(name); + } + /** + * Creates item under test @returns item under test + * + * @see net.sf.antcontrib.cpptasks.compiler.TestAbstractProcessor#create() + */ + protected AbstractProcessor create() { + return GccLibrarian.getInstance(); + } + /** + * Override of + * + * @see net.sf.antcontrib.cpptasks.compiler.TestAbstractProcessor#testBid() + */ + public void testBid() { + AbstractProcessor compiler = create(); + int bid = compiler.bid("c:/foo\\bar\\hello.o"); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, bid); + } + public void testGetIdentfier() { + AbstractProcessor processor = create(); + String id = processor.getIdentifier(); + assertTrue(id.indexOf("ar") >= 0); + } + /** + * Tests for library patterns + * + * See patch [ 676276 ] Enhanced support for Mac OS X + */ + public void testGetLibraryPatterns() { + String[] libnames = new String[]{"foo"}; + String[] patterns = ((AbstractArLibrarian) create()) + .getLibraryPatterns(libnames, null); + assertEquals(0, patterns.length); + } + /** + * Tests output file for ar library + * + * See bug [ 687732 ] Filenames for gcc static library does start with lib + */ + public void testOutputFileName() { + String[] outputFiles = GccLibrarian.getInstance().getOutputFileNames("x", null); + assertEquals("libx.a", outputFiles[0]); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractLdLinker.java b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractLdLinker.java new file mode 100644 index 0000000..63996c5 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestAbstractLdLinker.java @@ -0,0 +1,247 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; +import java.util.Vector; + +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.OutputTypeEnum; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +/** + * Test ld linker adapter abstract base class + * + * Override create to test concrete compiler implementions + */ +public class TestAbstractLdLinker extends TestCase { + private final String realOSName; + public TestAbstractLdLinker(String name) { + super(name); + realOSName = System.getProperty("os.name"); + } + protected AbstractLdLinker getLinker() { + return GccLinker.getInstance(); + } + protected void tearDown() throws java.lang.Exception { + System.setProperty("os.name", realOSName); + } + /** + * Checks for proper arguments for plugin generation on Darwin + * + * See [ 676276 ] Enhanced support for Mac OS X + */ + public void testAddImpliedArgsDarwinPlugin() { + System.setProperty("os.name", "Mac OS X"); + AbstractLdLinker linker = getLinker(); + Vector args = new Vector(); + LinkType pluginType = new LinkType(); + OutputTypeEnum pluginOutType = new OutputTypeEnum(); + pluginOutType.setValue("plugin"); + pluginType.setOutputType(pluginOutType); + linker.addImpliedArgs(false, pluginType, args); + assertEquals(1, args.size()); + assertEquals("-bundle", args.elementAt(0)); + } + /** + * Checks for proper arguments for shared generation on Darwin + * + * See [ 676276 ] Enhanced support for Mac OS X + */ + public void testAddImpliedArgsDarwinShared() { + System.setProperty("os.name", "Mac OS X"); + AbstractLdLinker linker = getLinker(); + Vector args = new Vector(); + LinkType pluginType = new LinkType(); + OutputTypeEnum pluginOutType = new OutputTypeEnum(); + pluginOutType.setValue("shared"); + pluginType.setOutputType(pluginOutType); + linker.addImpliedArgs(false, pluginType, args); + assertEquals(2, args.size()); + assertEquals("-prebind", args.elementAt(0)); + assertEquals("-dynamiclib", args.elementAt(1)); + } + /** + * Checks for proper arguments for plugin generation on Darwin + * + * See [ 676276 ] Enhanced support for Mac OS X + */ + public void testAddImpliedArgsNonDarwinPlugin() { + System.setProperty("os.name", "VAX/VMS"); + AbstractLdLinker linker = getLinker(); + Vector args = new Vector(); + LinkType pluginType = new LinkType(); + OutputTypeEnum pluginOutType = new OutputTypeEnum(); + pluginOutType.setValue("plugin"); + pluginType.setOutputType(pluginOutType); + linker.addImpliedArgs(false, pluginType, args); + assertEquals(1, args.size()); + assertEquals("-shared", args.elementAt(0)); + } + /** + * Checks for proper arguments for shared generation on Darwin + * + * See [ 676276 ] Enhanced support for Mac OS X + */ + public void testAddImpliedArgsNonDarwinShared() { + System.setProperty("os.name", "VAX/VMS"); + AbstractLdLinker linker = getLinker(); + Vector args = new Vector(); + LinkType pluginType = new LinkType(); + OutputTypeEnum pluginOutType = new OutputTypeEnum(); + pluginOutType.setValue("shared"); + pluginType.setOutputType(pluginOutType); + linker.addImpliedArgs(false, pluginType, args); + assertEquals(1, args.size()); + assertEquals("-shared", args.elementAt(0)); + } + public void testAddLibrarySetDirSwitch() { + AbstractLdLinker linker = getLinker(); + CCTask task = new CCTask(); + LibrarySet[] sets = new LibrarySet[]{new LibrarySet()}; + /* throws an Exception in setLibs otherwise */ + sets[0].setProject(new org.apache.tools.ant.Project()); + sets[0].setDir(new File("/foo")); + sets[0].setLibs(new CUtil.StringArrayBuilder("bart,cart,dart")); + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + String[] rc = linker.addLibrarySets(task, sets, preargs, midargs, + endargs); + String libdirSwitch = (String) endargs.elementAt(0); + assertEquals(libdirSwitch.substring(0, 2), "-L"); + // + // can't have space after -L or will break Mac OS X + // + assertTrue(!libdirSwitch.substring(2, 3).equals(" ")); + assertEquals(libdirSwitch.substring(libdirSwitch.length() - 3), "foo"); + } + public void testAddLibrarySetLibSwitch() { + AbstractLdLinker linker = getLinker(); + CCTask task = new CCTask(); + LibrarySet[] sets = new LibrarySet[]{new LibrarySet()}; + /* throws an Exception in setLibs otherwise */ + sets[0].setProject(new org.apache.tools.ant.Project()); + sets[0].setDir(new File("/foo")); + sets[0].setLibs(new CUtil.StringArrayBuilder("bart,cart,dart")); + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + String[] rc = linker.addLibrarySets(task, sets, preargs, midargs, + endargs); + assertEquals("-lbart", (String) endargs.elementAt(1)); + assertEquals("-lcart", (String) endargs.elementAt(2)); + assertEquals("-ldart", (String) endargs.elementAt(3)); + assertEquals(endargs.size(), 4); + } + public void testAddLibrarySetLibFrameworkNonDarwin() { + System.setProperty("os.name", "VAX/VMS"); + AbstractLdLinker linker = getLinker(); + CCTask task = new CCTask(); + LibrarySet[] sets = new LibrarySet[]{new LibrarySet()}; + /* throws an Exception in setLibs otherwise */ + sets[0].setProject(new org.apache.tools.ant.Project()); + sets[0].setDir(new File("/foo")); + LibraryTypeEnum libType = new LibraryTypeEnum(); + libType.setValue("framework"); + sets[0].setType(libType); + sets[0].setLibs(new CUtil.StringArrayBuilder("bart,cart,dart")); + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + String[] rc = linker.addLibrarySets(task, sets, preargs, midargs, + endargs); + assertEquals("-L", ((String) endargs.elementAt(0)).substring(0, 2)); + assertEquals("-Bdynamic", (String) endargs.elementAt(1)); + assertEquals("-lbart", (String) endargs.elementAt(2)); + assertEquals("-lcart", (String) endargs.elementAt(3)); + assertEquals("-ldart", (String) endargs.elementAt(4)); + assertEquals(endargs.size(), 5); + } + public void testAddLibrarySetLibFrameworkDarwin() { + System.setProperty("os.name", "Mac OS X"); + AbstractLdLinker linker = getLinker(); + CCTask task = new CCTask(); + LibrarySet[] sets = new LibrarySet[]{new LibrarySet()}; + /* throws an Exception in setLibs otherwise */ + sets[0].setProject(new org.apache.tools.ant.Project()); + sets[0].setDir(new File("/foo")); + LibraryTypeEnum libType = new LibraryTypeEnum(); + libType.setValue("framework"); + sets[0].setType(libType); + sets[0].setLibs(new CUtil.StringArrayBuilder("bart,cart,dart")); + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + String[] rc = linker.addLibrarySets(task, sets, preargs, midargs, + endargs); + assertEquals("-F", ((String) endargs.elementAt(0)).substring(0, 2)); + assertEquals("-framework bart", (String) endargs.elementAt(1)); + assertEquals("-framework cart", (String) endargs.elementAt(2)); + assertEquals("-framework dart", (String) endargs.elementAt(3)); + assertEquals(endargs.size(), 4); + } + public void testAddLibraryStatic() { + AbstractLdLinker linker = getLinker(); + CCTask task = new CCTask(); + LibrarySet[] sets = new LibrarySet[]{ + new LibrarySet(), + new LibrarySet(), + new LibrarySet()}; + /* throws an Exception in setLibs otherwise */ + sets[0].setProject(new org.apache.tools.ant.Project()); + sets[0].setLibs(new CUtil.StringArrayBuilder("bart")); + sets[1].setProject(new org.apache.tools.ant.Project()); + sets[1].setLibs(new CUtil.StringArrayBuilder("cart")); + LibraryTypeEnum libType = new LibraryTypeEnum(); + libType.setValue("static"); + sets[1].setType(libType); + sets[2].setProject(new org.apache.tools.ant.Project()); + sets[2].setLibs(new CUtil.StringArrayBuilder("dart")); + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + String[] rc = linker.addLibrarySets(task, sets, preargs, midargs, + endargs); + assertEquals("-lbart", (String) endargs.elementAt(0)); + assertEquals("-Bstatic", (String) endargs.elementAt(1)); + assertEquals("-lcart", (String) endargs.elementAt(2)); + assertEquals("-Bdynamic", (String) endargs.elementAt(3)); + assertEquals("-ldart", (String) endargs.elementAt(4)); + assertEquals(endargs.size(), 5); + } + public void testLibReturnValue() { + AbstractLdLinker linker = getLinker(); + CCTask task = new CCTask(); + LibrarySet[] sets = new LibrarySet[]{new LibrarySet()}; + /* throws an Exception in setLibs otherwise */ + sets[0].setProject(new org.apache.tools.ant.Project()); + sets[0].setDir(new File("/foo")); + sets[0].setLibs(new CUtil.StringArrayBuilder("bart,cart,dart")); + Vector preargs = new Vector(); + Vector midargs = new Vector(); + Vector endargs = new Vector(); + String[] rc = linker.addLibrarySets(task, sets, preargs, midargs, + endargs); + assertEquals(3, rc.length); + assertEquals("bart", rc[0]); + assertEquals("cart", rc[1]); + assertEquals("dart", rc[2]); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCCompiler.java new file mode 100644 index 0000000..3abe409 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCCompiler.java @@ -0,0 +1,80 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.io.File; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +import net.sf.antcontrib.cpptasks.parser.CParser; +import net.sf.antcontrib.cpptasks.parser.FortranParser; +import net.sf.antcontrib.cpptasks.parser.Parser; +/** + * Test gcc compiler adapter + * + */ +public class TestGccCCompiler extends TestGccCompatibleCCompiler { + public TestGccCCompiler(String name) { + super(name); + } + protected GccCompatibleCCompiler create() { + return GccCCompiler.getInstance(); + } + public void testBidObjectiveAssembly() { + GccCCompiler compiler = GccCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.s")); + } + public void testBidObjectiveC() { + GccCCompiler compiler = GccCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.m")); + } + public void testBidObjectiveCpp() { + GccCCompiler compiler = GccCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.mm")); + } + public void testBidPreprocessedCpp() { + GccCCompiler compiler = GccCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.ii")); + } + public void testCreateCParser1() { + Parser parser = GccCCompiler.getInstance().createParser( + new File("foo.c")); + assertTrue(parser instanceof CParser); + } + public void testCreateCParser2() { + Parser parser = GccCCompiler.getInstance().createParser( + new File("foo.")); + assertTrue(parser instanceof CParser); + } + public void testCreateCParser3() { + Parser parser = GccCCompiler.getInstance() + .createParser(new File("foo")); + assertTrue(parser instanceof CParser); + } + public void testCreateFortranParser1() { + Parser parser = GccCCompiler.getInstance().createParser( + new File("foo.f")); + assertTrue(parser instanceof FortranParser); + } + public void testCreateFortranParser2() { + Parser parser = GccCCompiler.getInstance().createParser( + new File("foo.FoR")); + assertTrue(parser instanceof FortranParser); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCompatibleCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCompatibleCCompiler.java new file mode 100644 index 0000000..68fab2e --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccCompatibleCCompiler.java @@ -0,0 +1,105 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import java.util.Vector; + +import junit.framework.TestCase; +/** + * Tests for gcc compatible compilers + * + * @author CurtA + */ +public abstract class TestGccCompatibleCCompiler extends TestCase { + /** + * Constructor + * + * @param name + * test case name + */ + public TestGccCompatibleCCompiler(String name) { + super(name); + } + /** + * Compiler creation method + * + * Must be overriden by extending classes + * + * @return GccCompatibleCCompiler + */ + protected abstract GccCompatibleCCompiler create(); + /** + * Tests command lines switches for warning = 0 + */ + public void testWarningLevel0() { + GccCompatibleCCompiler compiler = create(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 0); + assertEquals(1, args.size()); + assertEquals("-w", args.elementAt(0)); + } + /** + * Tests command lines switches for warning = 1 + */ + public void testWarningLevel1() { + GccCompatibleCCompiler compiler = create(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 1); + assertEquals(0, args.size()); + } + /** + * Tests command lines switches for warning = 2 + */ + public void testWarningLevel2() { + GccCompatibleCCompiler compiler = create(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 2); + assertEquals(0, args.size()); + } + /** + * Tests command lines switches for warning = 3 + */ + public void testWarningLevel3() { + GccCompatibleCCompiler compiler = create(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 3); + assertEquals(1, args.size()); + assertEquals("-Wall", args.elementAt(0)); + } + /** + * Tests command lines switches for warning = 4 + */ + public void testWarningLevel4() { + GccCompatibleCCompiler compiler = create(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 4); + assertEquals(2, args.size()); + assertEquals("-W", args.elementAt(0)); + assertEquals("-Wall", args.elementAt(1)); + } + /** + * Tests command lines switches for warning = 5 + */ + public void testWarningLevel5() { + GccCompatibleCCompiler compiler = create(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 5); + assertEquals(3, args.size()); + assertEquals("-Werror", args.elementAt(0)); + assertEquals("-W", args.elementAt(1)); + assertEquals("-Wall", args.elementAt(2)); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccLinker.java b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccLinker.java new file mode 100644 index 0000000..84e8d57 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/gcc/TestGccLinker.java @@ -0,0 +1,79 @@ +/* + * + * Copyright 2003-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.gcc; +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.OutputTypeEnum; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.compiler.Linker; +/** + * @author CurtA + */ +public class TestGccLinker extends TestCase { + private final String realOSName; + /** + * Constructor + * + * @param name test name + */ + public TestGccLinker(String name) { + super(name); + realOSName = System.getProperty("os.name"); + } + protected void tearDown() throws java.lang.Exception { + System.setProperty("os.name", realOSName); + } + public void testGetLinkerDarwinPlugin() { + System.setProperty("os.name", "Mac OS X"); + GccLinker linker = GccLinker.getInstance(); + OutputTypeEnum outputType = new OutputTypeEnum(); + outputType.setValue("plugin"); + LinkType linkType = new LinkType(); + linkType.setOutputType(outputType); + Linker pluginLinker = linker.getLinker(linkType); + assertEquals("libfoo.bundle", pluginLinker.getOutputFileNames("foo", null)[0]); + } + public void testGetLinkerDarwinShared() { + System.setProperty("os.name", "Mac OS X"); + GccLinker linker = GccLinker.getInstance(); + OutputTypeEnum outputType = new OutputTypeEnum(); + outputType.setValue("shared"); + LinkType linkType = new LinkType(); + linkType.setOutputType(outputType); + Linker sharedLinker = linker.getLinker(linkType); + assertEquals("libfoo.dylib", sharedLinker.getOutputFileNames("foo", null)[0]); + } + public void testGetLinkerNonDarwinPlugin() { + System.setProperty("os.name", "Microsoft Windows"); + GccLinker linker = GccLinker.getInstance(); + OutputTypeEnum outputType = new OutputTypeEnum(); + outputType.setValue("plugin"); + LinkType linkType = new LinkType(); + linkType.setOutputType(outputType); + Linker pluginLinker = linker.getLinker(linkType); + assertEquals("libfoo.so", pluginLinker.getOutputFileNames("foo", null)[0]); + } + public void testGetLinkerNonDarwinShared() { + System.setProperty("os.name", "Microsoft Windows"); + GccLinker linker = GccLinker.getInstance(); + OutputTypeEnum outputType = new OutputTypeEnum(); + outputType.setValue("shared"); + LinkType linkType = new LinkType(); + linkType.setOutputType(outputType); + Linker sharedLinker = linker.getLinker(linkType); + assertEquals("libfoo.so", sharedLinker.getOutputFileNames("foo", null)[0]); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/hp/TestaCCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/hp/TestaCCCompiler.java new file mode 100644 index 0000000..073463e --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/hp/TestaCCCompiler.java @@ -0,0 +1,93 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.hp; +import java.util.Vector; + +import junit.framework.TestCase; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +/** + * Test HP aCC compiler adapter + * + */ +// TODO Since aCCCompiler extends GccCompatibleCCompiler, this test +// should probably extend TestGccCompatibleCCompiler. +public class TestaCCCompiler extends TestCase { + public TestaCCCompiler(String name) { + super(name); + } + public void testBidC() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.c")); + } + public void testBidCpp() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.C")); + } + public void testBidCpp2() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cc")); + } + public void testBidCpp3() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.CC")); + } + public void testBidCpp4() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cxx")); + } + public void testBidCpp5() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.CXX")); + } + public void testBidCpp6() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cpp")); + } + public void testBidCpp7() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.CPP")); + } + public void testBidCpp8() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.c++")); + } + public void testBidCpp9() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.C++")); + } + public void testBidPreprocessed() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.i")); + } + public void testBidAssembly() { + aCCCompiler compiler = aCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.s")); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/ibm/TestVisualAgeCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/ibm/TestVisualAgeCCompiler.java new file mode 100644 index 0000000..62a513e --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/ibm/TestVisualAgeCCompiler.java @@ -0,0 +1,68 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.ibm; +import java.util.Vector; + +import junit.framework.TestCase; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +/** + * Test IBM Visual Age compiler adapter + * + */ +// TODO Since VisualAgeCCompiler extends GccCompatibleCCompiler, this test +// should probably extend TestGccCompatibleCCompiler. +public class TestVisualAgeCCompiler extends TestCase { + public TestVisualAgeCCompiler(String name) { + super(name); + } + public void testBidC() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.c")); + } + public void testBidCpp() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.C")); + } + public void testBidCpp2() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cc")); + } + public void testBidCpp3() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cxx")); + } + public void testBidCpp4() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cpp")); + } + public void testBidPreprocessed() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.i")); + } + public void testBidAssembly() { + VisualAgeCCompiler compiler = VisualAgeCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.s")); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/package.html b/src/test/java/net/sf/antcontrib/cpptasks/package.html new file mode 100644 index 0000000..eba4e2c --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/package.html @@ -0,0 +1,28 @@ + + + + + + + +JUnit tests for the net.sf.antcontrib.cpptasks package. + + + + diff --git a/src/test/java/net/sf/antcontrib/cpptasks/parser/TestCParser.java b/src/test/java/net/sf/antcontrib/cpptasks/parser/TestCParser.java new file mode 100644 index 0000000..d5e9888 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/parser/TestCParser.java @@ -0,0 +1,199 @@ +/* + * + * Copyright 2002-2005 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.parser; + +import junit.framework.TestCase; + +import java.io.CharArrayReader; +import java.io.IOException; + +/** + * Tests for the CParser class. + */ +public final class TestCParser + extends TestCase { + /** + * Constructor. + * @param name String test name + */ + public TestCParser(final String name) { + super(name); + } + + /** + * Checks parsing of #include . + * @throws IOException test fails on IOException + */ + public void testImmediateImportBracket() throws IOException { + CharArrayReader reader = new CharArrayReader( + "#import nowhatever ".toCharArray()); + CParser parser = new CParser(); + parser.parse(reader); + String[] includes = parser.getIncludes(); + assertEquals(includes.length, 1); + assertEquals("foo.h", includes[0]); + } + + /** + * Checks parsing of #import "foo.h". + * @throws IOException test fails on IOException + */ + public void testImmediateImportQuote() throws IOException { + CharArrayReader reader = new CharArrayReader("#import \"foo.h\" " + .toCharArray()); + CParser parser = new CParser(); + parser.parse(reader); + String[] includes = parser.getIncludes(); + assertEquals(includes.length, 1); + assertEquals("foo.h", includes[0]); + } + + /** + * Checks parsing of #include . + * @throws IOException test fails on IOException + */ + public void testImmediateIncludeBracket() throws IOException { + CharArrayReader reader = new CharArrayReader("#include " + .toCharArray()); + CParser parser = new CParser(); + parser.parse(reader); + String[] includes = parser.getIncludes(); + assertEquals(includes.length, 1); + assertEquals("foo.h", includes[0]); + } + + /** + * Checks parsing of #include "foo.h". + * @throws IOException test fails on IOException. + */ + public void testImmediateIncludeQuote() throws IOException { + CharArrayReader reader = new CharArrayReader( + "#include \"foo.h\" ".toCharArray()); + CParser parser = new CParser(); + parser.parse(reader); + String[] includes = parser.getIncludes(); + assertEquals(includes.length, 1); + assertEquals("foo.h", includes[0]); + } + + /** + * Checks parsing of #import + + + + + + +JUnit tests for the net.sf.antcontrib.cpptasks.parser package. + + + diff --git a/src/test/java/net/sf/antcontrib/cpptasks/sun/TestForteCCCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/sun/TestForteCCCompiler.java new file mode 100644 index 0000000..df08539 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/sun/TestForteCCCompiler.java @@ -0,0 +1,132 @@ +/* + * + * Copyright 2002-2007 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.sun; +import java.util.Vector; + +import junit.framework.TestCase; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +/** + * Test Sun Forte compiler adapter + * + */ +// TODO Since ForteCCCompiler extends GccCompatibleCCompiler, this test +// should probably extend TestGccCompatibleCCompiler. +public class TestForteCCCompiler extends TestCase { + public TestForteCCCompiler(String name) { + super(name); + } + public void testBidC() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.c")); + } + public void testBidCpp() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.C")); + } + public void testBidCpp2() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cc")); + } + public void testBidCpp3() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cxx")); + } + public void testBidCpp4() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.cpp")); + } + public void testBidCpp5() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.c++")); + } + public void testBidPreprocessed() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.i")); + } + public void testBidAssembly() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + assertEquals(AbstractProcessor.DEFAULT_PROCESS_BID, compiler + .bid("foo.s")); + } + /** + * Tests command line switches for warning = 0 + */ + public void testWarningLevel0() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 0); + assertEquals(1, args.size()); + assertEquals("-w", args.elementAt(0)); + } + /** + * Tests command line switches for warning = 1 + */ + public void testWarningLevel1() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 1); + assertEquals(0, args.size()); + } + /** + * Tests command line switches for warning = 2 + */ + public void testWarningLevel2() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 2); + assertEquals(0, args.size()); + } + /** + * Tests command line switches for warning = 3 + */ + public void testWarningLevel3() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 3); + assertEquals(1, args.size()); + assertEquals("+w", args.elementAt(0)); + } + /** + * Tests command line switches for warning = 4 + */ + public void testWarningLevel4() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 4); + assertEquals(1, args.size()); + assertEquals("+w2", args.elementAt(0)); + } + /** + * Tests command line switches for warning = 5 + */ + public void testWarningLevel5() { + ForteCCCompiler compiler = ForteCCCompiler.getInstance(); + Vector args = new Vector(); + compiler.addWarningSwitch(args, 5); + assertEquals(2, args.size()); + assertEquals("+w2", args.elementAt(0)); + assertEquals("-xwe", args.elementAt(1)); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectCompiler.java b/src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectCompiler.java new file mode 100644 index 0000000..6d97c12 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectCompiler.java @@ -0,0 +1,74 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.trolltech; + +import net.sf.antcontrib.cpptasks.compiler.AbstractProcessor; +import net.sf.antcontrib.cpptasks.compiler.TestAbstractCompiler; + +/** + * Tests for Trolltech Meta Object Compiler. + * + */ +public class TestMetaObjectCompiler + extends TestAbstractCompiler { + /** + * Constructor. + * @param name test name + */ + public TestMetaObjectCompiler(final String name) { + super(name); + } + + /** + * Creates compiler for inherited tests. + * @return AbstractProcessor compiler + */ + protected AbstractProcessor create() { + return MetaObjectCompiler.getInstance(); + } + + /** + * Gets default output file extension. + * @return String output file extension + */ + protected String getObjectExtension() { + return ".moc"; + } + + /** + * Skip testGetIdentifier. + */ + public void testGetIdentfier() { + } + + /** + * Override inherited test. + */ + public void testGetOutputFileName1() { + AbstractProcessor compiler = MetaObjectCompiler.getInstance(); + String[] output = compiler.getOutputFileNames("c:/foo\\bar\\hello.cpp", null); + assertEquals("hello" + getObjectExtension(), output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar/hello.cpp", null); + assertEquals("hello" + getObjectExtension(), output[0]); + output = compiler.getOutputFileNames("hello.cpp", null); + assertEquals("hello" + getObjectExtension(), output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar\\hello.h", null); + assertEquals("moc_hello.cpp", output[0]); + output = compiler.getOutputFileNames("c:/foo\\bar/hello.h", null); + assertNull("moc_hello.cpp", output[0]); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectParser.java b/src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectParser.java new file mode 100644 index 0000000..371bdf1 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/trolltech/TestMetaObjectParser.java @@ -0,0 +1,58 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.trolltech; + +import java.io.CharArrayReader; +import java.io.IOException; +import junit.framework.TestCase; + +/** + * Tests for the MetaObjectParser class. + */ +public final class TestMetaObjectParser + extends TestCase { + /** + * Constructor. + * @param name String test name + */ + public TestMetaObjectParser(final String name) { + super(name); + } + + /** + * Test that the presence of Q_OBJECT causes hasQObject to return true. + * @throws IOException test fails on IOException + */ + public void testHasQObject1() throws IOException { + CharArrayReader reader = new CharArrayReader( + " Q_OBJECT ".toCharArray()); + boolean hasQObject = MetaObjectParser.hasQObject(reader); + assertTrue(hasQObject); + } + + /** + * Test that the lack of Q_OBJECT causes hasQObject to return false. + * @throws IOException test fails on IOException + */ + public void testHasQObject2() throws IOException { + CharArrayReader reader = new CharArrayReader( + " Q_OBJ ECT ".toCharArray()); + boolean hasQObject = MetaObjectParser.hasQObject(reader); + assertFalse(hasQObject); + } + +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/trolltech/package.html b/src/test/java/net/sf/antcontrib/cpptasks/trolltech/package.html new file mode 100644 index 0000000..bbdaa89 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/trolltech/package.html @@ -0,0 +1,27 @@ + + + + + + + +Tests for Trolltech Qt uic and moc compilers. + + + diff --git a/src/test/java/net/sf/antcontrib/cpptasks/types/TestDefineArgument.java b/src/test/java/net/sf/antcontrib/cpptasks/types/TestDefineArgument.java new file mode 100644 index 0000000..e5b53ee --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/types/TestDefineArgument.java @@ -0,0 +1,124 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.types; +import junit.framework.TestCase; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +/** + * Tests for the DefineArgument class + */ +public class TestDefineArgument extends TestCase { + public TestDefineArgument(String name) { + super(name); + } + public void testIsActive1() { + DefineArgument arg = new DefineArgument(); + Project project = new Project(); + try { + boolean isActive = arg.isActive(project); + } catch (BuildException ex) { + return; + } + fail("isActive should throw exception if name is not set"); + } + public void testIsActive2() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + project.setProperty("cond", ""); + arg.setIf("cond"); + assertTrue(arg.isActive(project)); + } + public void testIsActive3() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + arg.setIf("cond"); + assertTrue(!arg.isActive(project)); + } + public void testIsActive4() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + project.setProperty("cond", "false"); + arg.setIf("cond"); + try { + boolean isActive = arg.isActive(project); + } catch (BuildException ex) { + return; + } + fail("Should throw exception for suspicious value"); + } + public void testIsActive5() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + project.setProperty("cond", ""); + arg.setUnless("cond"); + assertTrue(!arg.isActive(project)); + } + public void testIsActive6() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + arg.setUnless("cond"); + assertTrue(arg.isActive(project)); + } + public void testIsActive7() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + project.setProperty("cond", "false"); + arg.setUnless("cond"); + try { + boolean isActive = arg.isActive(project); + } catch (BuildException ex) { + return; + } + fail("Should throw exception for suspicious value"); + } + public void testIsActive8() { + DefineArgument arg = new DefineArgument(); + arg.setName("TEST"); + Project project = new Project(); + project.setProperty("cond", ""); + arg.setIf("cond"); + arg.setUnless("cond"); + assertTrue(!arg.isActive(project)); + } + public void testMerge() { + UndefineArgument[] base = new UndefineArgument[2]; + UndefineArgument[] specific = new UndefineArgument[2]; + base[0] = new DefineArgument(); + base[0].setName("foo"); + base[1] = new UndefineArgument(); + base[1].setName("hello"); + specific[0] = new DefineArgument(); + specific[0].setName("hello"); + specific[1] = new UndefineArgument(); + specific[1].setName("world"); + UndefineArgument[] merged = UndefineArgument.merge(base, specific); + assertEquals(3, merged.length); + assertEquals("foo", merged[0].getName()); + assertEquals(true, merged[0].isDefine()); + assertEquals("hello", merged[1].getName()); + assertEquals(true, merged[1].isDefine()); + assertEquals("world", merged[2].getName()); + assertEquals(false, merged[2].isDefine()); + } +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/types/TestLibrarySet.java b/src/test/java/net/sf/antcontrib/cpptasks/types/TestLibrarySet.java new file mode 100644 index 0000000..180f765 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/types/TestLibrarySet.java @@ -0,0 +1,337 @@ +/* + * + * Copyright 2002-2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.sf.antcontrib.cpptasks.types; + +import java.io.File; +import java.io.IOException; + +import junit.framework.TestCase; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.MockBuildListener; +import net.sf.antcontrib.cpptasks.MockFileCollector; +import net.sf.antcontrib.cpptasks.compiler.Linker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker; +import net.sf.antcontrib.cpptasks.devstudio.DevStudioLibrarian; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +/** + * Tests for the LibrarySet class. + */ +public class TestLibrarySet + extends TestCase { + + /** + * Constructor. + * + * @param name + * test name + */ + public TestLibrarySet(final String name) { + super(name); + } + + /** + * Evaluate isActive when "if" specifies a property that is set. + */ + public final void testIsActive1() { + LibrarySet libset = new LibrarySet(); + Project project = new Project(); + project.setProperty("windows", ""); + libset.setProject(project); + libset.setIf("windows"); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("kernel32"); + libset.setLibs(libs); + boolean isActive = libset.isActive(project); + assertTrue(isActive); + } + + /** + * Evaluate isActive when "if" specifies a property whose value suggests the + * user thinks the value is significant. + * + */ + public final void testIsActive2() { + LibrarySet libset = new LibrarySet(); + Project project = new Project(); + // + // setting the value to false should throw + // exception to warn user that they are misusing if + // + project.setProperty("windows", "false"); + libset.setIf("windows"); + try { + boolean isActive = libset.isActive(project); + } catch (BuildException ex) { + return; + } + fail(); + } + + /** + * Evaluate isActive when "if" specifies a property that is not set. + */ + public final void testIsActive3() { + LibrarySet libset = new LibrarySet(); + Project project = new Project(); + libset.setIf("windows"); + boolean isActive = libset.isActive(project); + assertTrue(!isActive); + } + + /** + * Evaluate isActive when "unless" specifies a property that is set. + * + */ + public final void testIsActive4() { + LibrarySet libset = new LibrarySet(); + Project project = new Project(); + project.setProperty("windows", ""); + libset.setUnless("windows"); + boolean isActive = libset.isActive(project); + assertTrue(!isActive); + } + + /** + * Evaluate isActive when "unless" specifies a property whose value suggests + * the user thinks the value is significant. + * + */ + public final void testIsActive5() { + LibrarySet libset = new LibrarySet(); + Project project = new Project(); + // + // setting the value to false should throw + // exception to warn user that they are misusing if + // + project.setProperty("windows", "false"); + libset.setUnless("windows"); + try { + boolean isActive = libset.isActive(project); + } catch (BuildException ex) { + return; + } + fail(); + } + + /** + * Evaluate isActive when "unless" specifies a property that is not set. + */ + public final void testIsActive6() { + LibrarySet libset = new LibrarySet(); + Project project = new Project(); + libset.setProject(project); + libset.setUnless("windows"); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("kernel32"); + libset.setLibs(libs); + boolean isActive = libset.isActive(project); + assertTrue(isActive); + } + + /** + * The libs parameter should not end with .lib, .so, .a etc New behavior is + * to warn if it ends in a suspicious extension. + */ + public final void testLibContainsDot() { + LibrarySet libset = new LibrarySet(); + Project p = new Project(); + MockBuildListener listener = new MockBuildListener(); + p.addBuildListener(listener); + libset.setProject(p); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("mylib1.1"); + libset.setLibs(libs); + assertEquals(0, listener.getMessageLoggedEvents().size()); + } + + /** + * The libs parameter should not end with .lib, .so, .a (that is, + * should be kernel, not kernel.lib). Previously the libset would + * warn on configuration, now provides more feedback + * when library is not found. + */ + public final void testLibContainsDotLib() { + LibrarySet libset = new LibrarySet(); + Project p = new Project(); + MockBuildListener listener = new MockBuildListener(); + p.addBuildListener(listener); + libset.setProject(p); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder( + "mylib1.lib"); + libset.setLibs(libs); + assertEquals(0, listener.getMessageLoggedEvents().size()); + } + + /** + * Use of a libset or syslibset without a libs attribute should log a + * warning message. + */ + public final void testLibNotSpecified() { + LibrarySet libset = new LibrarySet(); + Project p = new Project(); + MockBuildListener listener = new MockBuildListener(); + p.addBuildListener(listener); + libset.setProject(p); + boolean isActive = libset.isActive(p); + assertEquals(false, isActive); + assertEquals(1, listener.getMessageLoggedEvents().size()); + } + + /** + * this threw an exception prior to 2002-09-05 and started to throw one + * again 2002-11-19 up to 2002-12-11. + */ + public final void testShortLibName() { + LibrarySet libset = new LibrarySet(); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("li"); + libset.setProject(new Project()); + libset.setLibs(libs); + } + + /** + * The libs parameter should contain not a lib prefix (that is, + * pthread not libpthread). Previously the libset would + * warn on configuration, now provides more feedback + * when library is not found. + */ + public final void testStartsWithLib() { + LibrarySet libset = new LibrarySet(); + Project p = new Project(); + MockBuildListener listener = new MockBuildListener(); + p.addBuildListener(listener); + libset.setProject(p); + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder( + "libmylib1"); + libset.setLibs(libs); + assertEquals(0, listener.getMessageLoggedEvents().size()); + } + + /** + * This test creates two "fake" libraries in the temporary directory and + * check how many are visited. + * + * @param linker linker + * @param expected expected number of visited files + * @throws IOException + * if unable to write to temporary directory or delete temporary + * files + */ + public final void testVisitFiles(final Linker linker, + final int expected) + throws IOException { + LibrarySet libset = new LibrarySet(); + Project p = new Project(); + MockBuildListener listener = new MockBuildListener(); + p.addBuildListener(listener); + libset.setProject(p); + // + // create temporary files named cpptasksXXXXX.lib + // + File lib1 = File.createTempFile("cpptasks", ".lib"); + String lib1Name = lib1.getName(); + lib1Name = lib1Name.substring(0, lib1Name.indexOf(".lib")); + File lib2 = File.createTempFile("cpptasks", ".lib"); + File baseDir = lib1.getParentFile(); + + // set the dir attribute to the temporary directory + libset.setDir(baseDir); + // set libs to the file name without the suffix + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder(lib1Name); + libset.setLibs(libs); + + // + // collect all files visited + MockFileCollector collector = new MockFileCollector(); + libset.visitLibraries(p, linker, new File[0], collector); + + // + // get the canonical paths for the initial and visited libraries + String expectedCanonicalPath = lib1.getCanonicalPath(); + String actualCanonicalPath = null; + if (collector.size() == 1) { + actualCanonicalPath = new File(collector.getBaseDir(0), collector + .getFileName(0)).getCanonicalPath(); + } + // + // delete the temporary files + lib1.delete(); + lib2.delete(); + // was there only one match + assertEquals(expected, collector.size()); + if (expected == 1) { + // is its canonical path as expected + assertEquals(expectedCanonicalPath, actualCanonicalPath); + } + } + + /** + * Run testVisitFiles with the MSVC Linker + * expect one matching file. + * + * @throws IOException if unable to create or delete temporary file + */ + public final void testLinkerVisitFiles() throws IOException { + Linker linker = DevStudioLinker.getInstance(); + testVisitFiles(linker, 1); + } + + /** + * Run testVisitFiles with the MSVC Librarian + * expect one matching file. + * + * @throws IOException if unable to create or delete temporary file + */ + public final void testLibrarianVisitFiles() throws IOException { + Linker linker = DevStudioLibrarian.getInstance(); + testVisitFiles(linker, 0); + } + + + /** + * This test specifies a library pattern that should + * not match any available libraries and expects that + * a build exception will be raised. + * + * See bug 1380366 + */ + public final void testBadLibname() { + LibrarySet libset = new LibrarySet(); + Project p = new Project(); + MockBuildListener listener = new MockBuildListener(); + p.addBuildListener(listener); + libset.setProject(p); + // set libs to the file name without the suffix + CUtil.StringArrayBuilder libs = new CUtil.StringArrayBuilder("badlibname"); + libset.setLibs(libs); + + // + // collect all files visited + MockFileCollector collector = new MockFileCollector(); + try { + libset.visitLibraries(p, DevStudioLinker.getInstance(), new File[0], collector); + } catch(BuildException ex) { + return; + } +// +// code around line 320 in LibrarySet that would throw BuildException +// (and prevent reaching this line) is disabled since logic for identifying +// missing libraries does not work reliably on non-Windows platforms +// +// fail("visitLibraries should throw exception due to unsatisifed libname"); + } + +} diff --git a/src/test/java/net/sf/antcontrib/cpptasks/types/package.html b/src/test/java/net/sf/antcontrib/cpptasks/types/package.html new file mode 100644 index 0000000..e5efbc4 --- /dev/null +++ b/src/test/java/net/sf/antcontrib/cpptasks/types/package.html @@ -0,0 +1,28 @@ + + + + + + + +JUnit tests for the net.sf.antcontrib.cpptasks.types package. + + + + diff --git a/src/test/resources/openshore/dependencies.xml b/src/test/resources/openshore/dependencies.xml new file mode 100644 index 0000000..1644f84 --- /dev/null +++ b/src/test/resources/openshore/dependencies.xml @@ -0,0 +1,911 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/openshore/history.xml b/src/test/resources/openshore/history.xml new file mode 100644 index 0000000..19fe515 --- /dev/null +++ b/src/test/resources/openshore/history.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/xerces-c/dependencies.xml b/src/test/resources/xerces-c/dependencies.xml new file mode 100644 index 0000000..f8d7324 --- /dev/null +++ b/src/test/resources/xerces-c/dependencies.xml @@ -0,0 +1,3330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/xerces-c/history.xml b/src/test/resources/xerces-c/history.xml new file mode 100644 index 0000000..2e8a3c0 --- /dev/null +++ b/src/test/resources/xerces-c/history.xml @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3