├── .clang-format ├── .editorconfig ├── .gitattributes ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── COPYING ├── README.md ├── appveyor.yml ├── bin ├── smp_project_generate_gpl3.bat ├── smp_project_generate_lgpl3.bat ├── smp_project_generate_noredist.bat └── smp_project_get_dependencies ├── include ├── configGenerator.h ├── helperFunctions.h └── projectGenerator.h ├── project_generate.sln ├── project_generate.vcxproj ├── project_generate.vcxproj.filters ├── source ├── Templates.rc ├── configGenerator.cpp ├── configGenerator_build.cpp ├── helperFunctions.cpp ├── projectGenerator.cpp ├── projectGenerator_build.cpp ├── projectGenerator_compiler.cpp ├── projectGenerator_dce.cpp ├── projectGenerator_files.cpp ├── projectGenerator_pass.cpp └── project_generate.cpp └── templates ├── smp_deps.props ├── smp_winrt_deps.props ├── template_files.props ├── template_in.sln ├── template_in.vcxproj ├── template_in.vcxproj.filters ├── template_in_winrt.sln ├── template_in_winrt.vcxproj ├── template_with_latest_sdk.bat ├── templateprogram_in.vcxproj └── templateprogram_in.vcxproj.filters /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: DontAlign 5 | AlignConsecutiveAssignments: false 6 | AlignConsecutiveDeclarations: false 7 | AlignConsecutiveMacros: false 8 | AlignEscapedNewlines: Left 9 | AlignOperands: false 10 | AlignTrailingComments: true 11 | AllowAllArgumentsOnNextLine: true 12 | AllowAllConstructorInitializersOnNextLine: true 13 | AllowAllParametersOfDeclarationOnNextLine: true 14 | AllowShortBlocksOnASingleLine: Never 15 | AllowShortCaseLabelsOnASingleLine: false 16 | AllowShortFunctionsOnASingleLine: None 17 | AllowShortIfStatementsOnASingleLine: Never 18 | AllowShortLambdasOnASingleLine: Inline 19 | AllowShortLoopsOnASingleLine: false 20 | AlwaysBreakAfterDefinitionReturnType: None 21 | AlwaysBreakAfterReturnType: None 22 | AlwaysBreakBeforeMultilineStrings: false 23 | AlwaysBreakTemplateDeclarations: Yes 24 | BinPackArguments: true 25 | BinPackParameters: true 26 | BraceWrapping: 27 | AfterCaseLabel: false 28 | AfterClass: true 29 | AfterControlStatement: false 30 | AfterEnum: true 31 | AfterFunction: true 32 | AfterNamespace: false 33 | AfterStruct: true 34 | AfterUnion: true 35 | AfterExternBlock: false 36 | BeforeCatch: false 37 | BeforeElse: false 38 | #BeforeLambdaBody: false 39 | IndentBraces: false 40 | SplitEmptyFunction: false 41 | SplitEmptyRecord: false 42 | SplitEmptyNamespace: false 43 | BreakAfterJavaFieldAnnotations: true 44 | BreakBeforeBinaryOperators: None 45 | BreakBeforeBraces: Custom 46 | BreakBeforeTernaryOperators: false 47 | BreakConstructorInitializers: BeforeComma 48 | BreakInheritanceList: BeforeComma 49 | BreakStringLiterals: false 50 | ColumnLimit: 120 51 | CompactNamespaces: false 52 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 53 | ConstructorInitializerIndentWidth: 4 54 | ContinuationIndentWidth: 4 55 | Cpp11BracedListStyle: true 56 | DeriveLineEnding: false 57 | DerivePointerAlignment: false 58 | DisableFormat: false 59 | ExperimentalAutoDetectBinPacking: false 60 | FixNamespaceComments: true 61 | IncludeBlocks: Regroup 62 | IncludeCategories: 63 | - Regex: '^"' 64 | Priority: 1 65 | - Regex: '^<' 66 | Priority: 2 67 | IncludeIsMainSourceRegex: '(.inl)$' 68 | #IndentCaseBlocks: false 69 | IndentCaseLabels: true 70 | IndentGotoLabels: false 71 | IndentPPDirectives: AfterHash 72 | IndentWidth: 4 73 | IndentWrappedFunctionNames: false 74 | KeepEmptyLinesAtTheStartOfBlocks: false 75 | MaxEmptyLinesToKeep: 1 76 | NamespaceIndentation: None 77 | PointerAlignment: Left 78 | ReflowComments: true 79 | SortIncludes: true 80 | SortUsingDeclarations: true 81 | SpaceAfterCStyleCast: false 82 | SpaceAfterLogicalNot: false 83 | SpaceAfterTemplateKeyword: false 84 | SpaceBeforeAssignmentOperators: true 85 | SpaceBeforeCpp11BracedList: false 86 | SpaceBeforeCtorInitializerColon: true 87 | SpaceBeforeInheritanceColon: true 88 | SpaceBeforeParens: ControlStatements 89 | SpaceBeforeRangeBasedForLoopColon: true 90 | SpaceBeforeSquareBrackets: false 91 | SpaceInEmptyBlock: false 92 | SpaceInEmptyParentheses: false 93 | SpacesBeforeTrailingComments: 1 94 | SpacesInAngles: false 95 | SpacesInCStyleCastParentheses: false 96 | SpacesInConditionalStatement: false 97 | SpacesInContainerLiterals: false 98 | SpacesInParentheses: false 99 | SpacesInSquareBrackets: false 100 | Standard: Auto #Latest 101 | TabWidth: 4 102 | UseCRLF: false 103 | UseTab: Never 104 | ... 105 | 106 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*.{c,c++,cc,config,cp,cpp,cu,cxx,h,hh,hpp,hxx,inc,inl] 3 | indent_style=space 4 | indent_size=4 5 | tab_width=4 6 | 7 | [*] 8 | 9 | # Standard properties 10 | end_of_line=lf 11 | insert_final_newline=true 12 | max_line_length=120 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sln text eol=crlf 2 | *.vcxproj text eol=crlf 3 | *.vcxproj.filters text eol=crlf 4 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing a pull-request to this repository, please first discuss the change you wish to make via issue 4 | with the owners of this repository before making a change. Ensure that the change is only related to functionality 5 | provided by this project only. 6 | 7 | Please note we have a code of conduct, please follow it in all your interactions with the project. 8 | 9 | ## Submitting Changes 10 | 11 | Changes are excepted by submitting a pull request directly to the projects Github page. 12 | When creating the pull request the provided template should be used to ensure all required information is provided. 13 | 14 | ## Code of Conduct 15 | 16 | ### Our Pledge 17 | 18 | In the interest of fostering an open and welcoming environment, we as 19 | contributors and maintainers pledge to making participation in our project and 20 | our community a harassment-free experience for everyone, regardless of age, body 21 | size, disability, ethnicity, gender identity and expression, level of experience, 22 | nationality, personal appearance, race, religion, or sexual identity and 23 | orientation. 24 | 25 | ### Our Standards 26 | 27 | Examples of behavior that contributes to creating a positive environment 28 | include: 29 | 30 | * Using welcoming and inclusive language 31 | * Being respectful of differing viewpoints and experiences 32 | * Gracefully accepting constructive criticism 33 | * Focusing on what is best for the community 34 | * Showing empathy towards other community members 35 | 36 | Examples of unacceptable behavior by participants include: 37 | 38 | * The use of sexualized language or imagery and unwelcome sexual attention or 39 | advances 40 | * Trolling, insulting/derogatory comments, and personal or political attacks 41 | * Public or private harassment 42 | * Publishing others' private information, such as a physical or electronic 43 | address, without explicit permission 44 | * Other conduct which could reasonably be considered inappropriate in a 45 | professional setting 46 | 47 | ### Our Responsibilities 48 | 49 | Project maintainers are responsible for clarifying the standards of acceptable 50 | behavior and are expected to take appropriate and fair corrective action in 51 | response to any instances of unacceptable behavior. 52 | 53 | Project maintainers have the right and responsibility to remove, edit, or 54 | reject comments, commits, code, wiki edits, issues, and other contributions 55 | that are not aligned to this Code of Conduct, or to ban temporarily or 56 | permanently any contributor for other behaviors that they deem inappropriate, 57 | threatening, offensive, or harmful. 58 | 59 | ### Scope 60 | 61 | This Code of Conduct applies both within project spaces and in public spaces 62 | when an individual is representing the project or its community. Examples of 63 | representing a project or community include using an official project e-mail 64 | address, posting via an official social media account, or acting as an appointed 65 | representative at an online or offline event. Representation of a project may be 66 | further defined and clarified by project maintainers. 67 | 68 | ### Enforcement 69 | 70 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 71 | reported by contacting the project team. All 72 | complaints will be reviewed and investigated and will result in a response that 73 | is deemed necessary and appropriate to the circumstances. The project team is 74 | obligated to maintain confidentiality with regard to the reporter of an incident. 75 | Further details of specific enforcement policies may be posted separately. 76 | 77 | Project maintainers who do not follow or enforce the Code of Conduct in good 78 | faith may face temporary or permanent repercussions as determined by other 79 | members of the project's leadership. 80 | 81 | ### Attribution 82 | 83 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 84 | available at [http://contributor-covenant.org/version/1/4][version] 85 | 86 | [homepage]: http://contributor-covenant.org 87 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## FFmpeg Version 4 | 5 | 6 | ## Command Line 7 | 8 | 9 | ## Your Environment 10 | 11 | * Visual Studio Version: 12 | * Operating System and Version: 13 | 14 | ## Possible Fix 15 | 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Context 4 | 5 | 6 | ## Current and Suggested Behavior 7 | 8 | 9 | ## Steps to Explain Enhancement 10 | 11 | 1. 12 | 2. 13 | 3. 14 | 4. 15 | 16 | ## Your Test Environment 17 | 18 | * Visual Studio Version Used: 19 | * Operating System and Version(s): -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.obj 2 | *.lib 3 | *.log 4 | *.tlog 5 | *.pdb 6 | *.ildb 7 | *.pgd 8 | *.pch 9 | *.manifest 10 | *.suo 11 | *.user 12 | *.sdf 13 | *.opensdf 14 | [Oo]bj/ 15 | *.exe 16 | !*.h 17 | !*.c 18 | !*.asm 19 | !*.def 20 | !*.rc 21 | *.sbr 22 | *.iobj 23 | *.ipdb 24 | .vs/ 25 | *.VC.db 26 | *.opendb 27 | *.ilk 28 | [Bb]in/* 29 | !smp_* 30 | *Caches/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FFVS-Project-Generator 2 | ============= 3 | [![Build status](https://ci.appveyor.com/api/projects/status/g6qqnx5t3qj60pei?svg=true)](https://ci.appveyor.com/project/Sibras/ffvs-project-generator) 4 | [![Github All Releases](https://img.shields.io/github/downloads/ShiftMediaProject/FFVS-Project-Generator/total.svg)](https://github.com/ShiftMediaProject/FFVS-Project-Generator/releases) 5 | [![GitHub release](https://img.shields.io/github/release/ShiftMediaProject/FFVS-Project-Generator.svg)](https://github.com/ShiftMediaProject/FFVS-Project-Generator/releases/latest) 6 | [![GitHub issues](https://img.shields.io/github/issues/ShiftMediaProject/FFVS-Project-Generator.svg)](https://github.com/ShiftMediaProject/FFVS-Project-Generator/issues) 7 | [![license](https://img.shields.io/github/license/ShiftMediaProject/FFVS-Project-Generator.svg)](https://github.com/ShiftMediaProject/FFVS-Project-Generator) 8 | [![donate](https://img.shields.io/badge/donate-link-brightgreen.svg)](https://shiftmediaproject.github.io/8-donate/) 9 | ## About 10 | 11 | The FFmpeg VS Project Generator is a standalone program that can be used to create a custom Visual Studio project within a FFmpeg source code distribution. This program allows for the created Visual Studio project to be customised using virtually any of the options supported by FFmpegs default configure script. This allows for selecting which dependency libraries and codec/format support should be built into the created project file. With the output project FFmpeg libraries and programs can be built and debugged directly within Visual Studio. 12 | 13 | ## FFmpeg 14 | 15 | FFmpeg is a collection of libraries and tools to process multimedia content such as audio, video, subtitles and related metadata. [https://ffmpeg.org](https://ffmpeg.org) 16 | 17 | ## Downloads 18 | 19 | Pre-built executables are available from the [releases](https://github.com/ShiftMediaProject/FFmpeg/releases) page in a single archive containing both 32bit and 64bit versions. 20 | 21 | ## Generating Custom Project Files 22 | 23 | This project comes with the project_generate program which can be used to build custom project files. 24 | This program accepts many of the configuration parameters that are supported by FFmpegs standard configure script (see FFmpegs documentation for more details). 25 | These options can be used to disable/enable specific options that define how FFmpeg is built. Using project_generate a new project can be built using these options. 26 | 27 | To generate a custom project using different configuration options simply build project_generate and then run it by passing in the desired config options. In order for the generator to run it must have access to the ffmpeg source files that should be built into the new generated project. The generator will search for the source **configure** file in order to find what options are avilable for the current sources. This file must be accessible for the program to run, if the generator cannot find the configure files location then the input command option **--rootdir=** can be used to specify its location. 28 | 29 | For example to build FFmpeg without any additional dependencies: 30 | 31 | ``` 32 | project_generate.exe --enable-gpl --enable-version3 --disable-bzlib --disable-iconv --disable-zlib --disable-lzma --disable-sdl --toolchain=msvc 33 | ``` 34 | 35 | As well as enabling/disabling dependency libraries, specific config options can also be enabled/disabled. For instance a project that does not require yasm can be built by passing **--disable-yasm**. Specific FFmpeg programs can also be disabled such as **--disable-ffprobe** which will prevent a project file being generated for the FFmpeg program ffprobe. 36 | 37 | The generator is designed to automatically resolve dependencies so if a configure option is disabled all options that depend on it will also be disabled accordingly. 38 | 39 | For a complete list of available commands the **--help** option can be passed to the generator. This will give the complete list of accepted options based on the current sources. 40 | 41 | By default the generator will build a project using the latest available toolchain detected on the host computer. This can be changed by hand in the generated projects properties **Project Configuration->General->Platform Toolset** if an older toolset is desired. The generator also supports use of the Intel compiler. The **--toolchain=** option can be used to change between standard Microsoft compiler (msvc) and the Intel compiler (icl). 42 | 43 | **Note:** FFmpeg requires C99 support in order to compile. Only Visual Studio 2013 or newer supports required C99 functionality and so any older version is not supported. Visual Studio 2013 or newer is required. If using an older unsupported version of Visual Studio the Intel compiler can be used to add in the required C99 capability. 44 | 45 | The project generator will also check the availability of dependencies. Any enabled options must have the appropriate headers installed in __*OutputDir__ otherwise an error will be generated. 46 | 47 | Sevaral automated batch files are supplied with the project that can be used to generate FFmpeg projects based on dependencies provided by ShiftMediaProject (smp_project_generate_gpl etc.). These batch files can be used to build projects based on various configurations and they can also optionally download all the appropriate dependency libraries that are supplied by ShiftMediaProject. 48 | 49 | * __OutputDir__ is the **Output Directory** specified in the project properties. 50 | **Note:** There is a different OutputDir for 32/64bit configurations. Lib's and DLL's should be placed in the correct directory. 51 | Any header files will need to be placed in the Output directories include folder **_OutputDir_\include**. 52 | By default the 32bit lib OutputDir is **_OutputDir_/lib/x86** and 64bit is **_OutputDir_/lib/x64**. DLLs follow a similar scheme except using **_OutputDir_/bin/x86** and for 64bit **_OutputDir_/bin/x64**. 53 | The default value of OutputDir is **..\..\msvc** relative to the FFmpeg source directory. An example of the expetced directory structure is: 54 | * msvc (OutputDir) 55 | * source > 56 | * FFmpeg 57 | * ..Any other libraries source code.. 58 | 59 | ## Using the Supplied Dependency Projects 60 | 61 | Many of the possible FFmpeg dependencies (and their dependencies) are provided by the ShiftMediaProject repositories. 62 | 63 | Many of the possible FFmpeg dependencies (and there dependencies) are available in the ShiftMediaProject repositories. 64 | However the following is a list of extra dependency options that require external downloads if used: 65 | 1. opengl (requires glext) 66 | 1. Download glext.h and wglext.h from opengl.org. 67 | 2. Save the header files into *OutputDir*/include/gl/*. 68 | 2. opencl (requires latest Intel/AMD OpenCL or NVIDIA CUDA SDK) 69 | 1. Download either the "Intel OpenCL SDK", "AMD OpenCL SDK" or the "NVIDIA CUDA SDK" from their respective suppliers. 70 | 2. Install the downloaded SDK wherever desired. 71 | 3. ffnvcodec/nvdec/nvenc (requires nv-codec-headers) 72 | 1. Download the nv-codec-headers repository from https://github.com/FFmpeg/nv-codec-headers 73 | 2. Save the contents of the nv-codec-headers repositories "include" folder into "OutputDir/include/*". 74 | 5. cuda-sdk (requires latest NVIDIA CUDA SDK) 75 | 1. Download the NVIDIA CUDA SDK from the NVIDIA website 76 | 2. Install the downloaded SDK wherever desired. 77 | 6. amf (requires Advanced Media Framework (AMF) SDK headers) 78 | 1. Download the AMF repository from https://github.com/GPUOpen-LibrariesAndSDKs/AMF 79 | 2. Save the contents of the AMF repositories "amf/public/include" into "OutputDir/include/AMF/*". 80 | 7. decklink (requires Blackmagic DeckLink SDK) 81 | 1. Download the "Blackmagic DeckLink SDK" from the Blackmagic website. 82 | 2. Extract the downloaded SDK wherever desired. 83 | 3. Run the following command from a Visual Studio developer command prompt in the "Win/include" folder: 84 | midl /win32 /h DeckLinkAPI.h DeckLinkAPI.idl 85 | 4. Copy the newly created "DeckLinkAPI.h" and "DeckLinkAPI_i.c" files to *OutputDir*/include/*. 86 | 8. vulkan (requires Vulkan headers or Vulkan SDK) 87 | 1. Download the Vulkan SDK from https://www.lunarg.com/vulkan-sdk/ 88 | 2. Install the downloaded SDK wherever desired. 89 | or 90 | 1. Download the vulkan-headers repository from https://github.com/KhronosGroup/Vulkan-Headers 91 | 2. Save the contents of the vulkan-headers repositories "include" folder into "OutputDir/include/*". 92 | 93 | Any dependencies supplied by ShiftMediaProject should be downloaded next to the FFmpeg folder as they will use the same OutputDir location. Projects to build each dependency can be found in the respective repository **./SMP** directories. 94 | 95 | Only dependencies built from supplied ShiftMediaProject repositories are tested and supported. Using compiled dependencies from other sources may result in version or other issues. Although these external sources generally work fine any problems associated with them are not covered by ShiftMediaProject and so they should be used with discretion. 96 | 97 | ## Building with ASM 98 | 99 | If the enable-nasm option is used to generate a project then in order to use the output project file using msvc you must first download and install NASM. 100 | NASM is required to compile all used assembly files. 101 | 102 | 1. Visual Studio NASM integration can be downloaded from https://github.com/ShiftMediaProject/VSNASM/releases/latest 103 | 2. Once downloaded simply follow the install instructions included in the download. 104 | 105 | Note: Older source versions of FFmpeg used YASM for assembly compilation instead of NASM if using an older source release then YASM integration will be needed instead. The installation of YASM is identical to that of NASM 106 | https://github.com/ShiftMediaProject/VSYASM/releases/latest 107 | 108 | ## License 109 | 110 | FFVS-Project-Generator itself is released under [LGPLv2](https://www.gnu.org/licenses/lgpl-2.0.html). The generated output project(s) and source can be used with existing FFmpeg source code such that any resultant binaries created by the generated projects will still conform to the license of the FFmpeg source code itself. This means the output binaries are licensed based on the command line specified when generating the projects (i.e. --enable-gpl etc.). -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | branches: 4 | only: 5 | - master 6 | skip_non_tags: true 7 | shallow_clone: true 8 | 9 | image: Visual Studio 2022 10 | 11 | configuration: Release 12 | 13 | platform: 14 | - x86 15 | - x64 16 | 17 | build: 18 | project: project_generate.sln 19 | parallel: true 20 | verbosity: minimal 21 | 22 | after_build: 23 | # Copy over readme to artifact folder 24 | - cmd: copy /y %APPVEYOR_BUILD_FOLDER%\README.md %APPVEYOR_BUILD_FOLDER%\bin 25 | 26 | artifacts: 27 | - path: bin 28 | name: $(APPVEYOR_PROJECT_NAME)_$(APPVEYOR_REPO_TAG_NAME)_$(PLATFORM) 29 | type: zip 30 | 31 | deploy: 32 | - provider: GitHub 33 | tag: $(APPVEYOR_REPO_TAG_NAME) 34 | description: Pre-built 32b and 64b executables for $(APPVEYOR_PROJECT_NAME) $(APPVEYOR_REPO_TAG_NAME) 35 | auth_token: 36 | secure: c9Sads7Y16h7FP+LrR3IjVygYAgh8GByE8TtazxDg7jpPVxc+XDV81z7MoUc2Ada 37 | artifact: $(APPVEYOR_PROJECT_NAME)_$(APPVEYOR_REPO_TAG_NAME)_$(PLATFORM) 38 | force_update: true -------------------------------------------------------------------------------- /bin/smp_project_generate_gpl3.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET UPSTREAMURL=https://github.com/ShiftMediaProject 4 | SET DEPENDENCIES=( ^ 5 | bzip2, ^ 6 | fontconfig, ^ 7 | freetype2, ^ 8 | fribidi, ^ 9 | game-music-emu, ^ 10 | gnutls, ^ 11 | harfbuzz, ^ 12 | lame, ^ 13 | libass, ^ 14 | libbluray, ^ 15 | libcdio, ^ 16 | libcdio-paranoia, ^ 17 | libiconv, ^ 18 | libgcrypt, ^ 19 | libilbc, ^ 20 | liblzma, ^ 21 | libssh, ^ 22 | libxml2, ^ 23 | libvpx, ^ 24 | mfx_dispatch, ^ 25 | modplug, ^ 26 | opus, ^ 27 | sdl, ^ 28 | soxr, ^ 29 | speex, ^ 30 | theora, ^ 31 | vorbis, ^ 32 | x264, ^ 33 | x265, ^ 34 | xvid, ^ 35 | zlib ^ 36 | ) 37 | SET PGOPTIONS=--enable-gpl --enable-version3 --enable-bzlib --enable-iconv --enable-lzma --enable-sdl2 --enable-zlib --enable-libmp3lame --enable-libvorbis --enable-libspeex --enable-libopus --enable-libilbc --enable-libtheora --enable-libx264 --enable-libx265 --enable-libxvid --enable-libvpx --enable-libgme --enable-libmodplug --enable-libsoxr --enable-libfreetype --enable-fontconfig --enable-libfribidi --enable-libharfbuzz --enable-libass --enable-libxml2 --enable-gnutls --disable-schannel --enable-gcrypt --enable-libssh --enable-libcdio --enable-libbluray --enable-libdvdread --enable-libdvdnav --enable-opengl --enable-libmfx --enable-ffnvcodec --enable-cuda --enable-amf --enable-vulkan 38 | 39 | REM Store current directory and ensure working directory is the location of current .bat 40 | SET CURRDIR=%CD% 41 | cd %~dp0 42 | 43 | REM Initialise error check value 44 | SET ERROR=0 45 | 46 | REM Check if executable can be located 47 | IF NOT EXIST "project_generate.exe" ( 48 | ECHO "Error: FFVS Project Generator executable file not found." 49 | IF EXIST "../.git" ( 50 | ECHO "Please build the executable using the supplied project before continuing." 51 | ) 52 | GOTO exitOnError 53 | ) 54 | 55 | REM Check if FFmpeg directory can be located 56 | SET SEARCHPATHS=(./, ../, ./ffmpeg/, ../ffmpeg/, ../../ffmpeg/, ../../../, ../../, ./source/ffmpeg, ../source/ffmpeg, ../../source/ffmpeg/) 57 | SET FFMPEGPATH= 58 | FOR %%I IN %SEARCHPATHS% DO ( 59 | IF EXIST "%%I/ffmpeg.h" ( 60 | SET FFMPEGPATH=%%I 61 | ) 62 | IF EXIST "%%I/fftools/ffmpeg.h" ( 63 | SET FFMPEGPATH=%%I 64 | ) 65 | ) 66 | IF "%FFMPEGPATH%"=="" ( 67 | ECHO Error: Failed finding FFmpeg source directory 68 | GOTO exitOnError 69 | ) ELSE ( 70 | ECHO Located FFmpeg source directory at "%FFMPEGPATH%" 71 | ECHO. 72 | ) 73 | 74 | REM Copy across the batch file used to auto get required dependencies 75 | CALL :makeGetDeps || GOTO exit 76 | 77 | REM Get/Update any used dependency libraries 78 | SET USERPROMPT=N 79 | SET /P USERPROMPT=Do you want to download/update the required dependency projects (Y/N)? 80 | IF /I "%USERPROMPT%"=="Y" ( 81 | ECHO. 82 | CALL :getDeps || GOTO exit 83 | ECHO Ensure that any dependency projects have been built using the supplied project within the dependencies ./SMP folder before continuing. 84 | ECHO Warning: Some used dependencies require a manual download. Consult the readme for instructions to install the following needed components: 85 | ECHO OpenGL 86 | PAUSE 87 | ) 88 | 89 | REM Run the executable 90 | ECHO Running project generator... 91 | project_generate.exe %PGOPTIONS% 92 | GOTO exit 93 | 94 | :makeGetDeps 95 | ECHO Creating project_get_dependencies.bat... 96 | FOR %%I IN %DEPENDENCIES% DO SET LASTDEP=%%I 97 | MKDIR "%FFMPEGPATH%/SMP" >NUL 2>&1 98 | ( 99 | ECHO @ECHO OFF 100 | ECHO SETLOCAL EnableDelayedExpansion 101 | ECHO. 102 | ECHO SET UPSTREAMURL=%UPSTREAMURL% 103 | ECHO SET DEPENDENCIES=( ^^ 104 | FOR %%I IN %DEPENDENCIES% DO ( 105 | IF "%%I"=="%LASTDEP%" ( 106 | ECHO %%I ^^ 107 | ) ELSE ( 108 | ECHO %%I, ^^ 109 | ) 110 | ) 111 | type smp_project_get_dependencies 112 | ) > "%FFMPEGPATH%/SMP/project_get_dependencies.bat" 113 | ECHO. 114 | EXIT /B %ERRORLEVEL% 115 | 116 | :getDeps 117 | REM Add current repo to list of already passed dependencies 118 | ECHO Getting and updating any required dependency libs... 119 | cd "%FFMPEGPATH%/SMP" 120 | CALL project_get_dependencies.bat "ffmpeg" || EXIT /B 1 121 | cd %~dp0 122 | ECHO. 123 | EXIT /B %ERRORLEVEL% 124 | 125 | :exitOnError 126 | SET ERROR=1 127 | 128 | :exit 129 | REM Check if this was launched from an existing terminal or directly from .bat 130 | REM If launched by executing the .bat then pause on completion 131 | cd %CURRDIR% 132 | ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1 133 | IF %ERRORLEVEL% == 0 IF "%~1"=="" PAUSE 134 | EXIT /B %ERROR% -------------------------------------------------------------------------------- /bin/smp_project_generate_lgpl3.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET UPSTREAMURL=https://github.com/ShiftMediaProject 4 | SET DEPENDENCIES=( ^ 5 | bzip2, ^ 6 | fontconfig, ^ 7 | freetype2, ^ 8 | fribidi, ^ 9 | game-music-emu, ^ 10 | gnutls, ^ 11 | harfbuzz, ^ 12 | lame, ^ 13 | libass, ^ 14 | libbluray, ^ 15 | libgcrypt, ^ 16 | libiconv, ^ 17 | libilbc, ^ 18 | liblzma, ^ 19 | libssh, ^ 20 | libxml2, ^ 21 | libvpx, ^ 22 | mfx_dispatch, ^ 23 | modplug, ^ 24 | opus, ^ 25 | sdl, ^ 26 | soxr, ^ 27 | speex, ^ 28 | theora, ^ 29 | vorbis, ^ 30 | zlib ^ 31 | ) 32 | SET PGOPTIONS=--enable-version3 --enable-bzlib --enable-iconv --enable-lzma --enable-sdl2 --enable-zlib --enable-libmp3lame --enable-libvorbis --enable-libspeex --enable-libopus --enable-libilbc --enable-libtheora --enable-libvpx --enable-libgme --enable-libmodplug --enable-libsoxr --enable-libfreetype --enable-fontconfig --enable-libfribidi --enable-libharfbuzz --enable-libass --enable-libxml2 --enable-gnutls --disable-schannel --enable-gcrypt --enable-libssh --enable-libbluray --enable-opengl --enable-libmfx --enable-ffnvcodec --enable-cuda --enable-amf --enable-vulkan 33 | 34 | REM Store current directory and ensure working directory is the location of current .bat 35 | SET CURRDIR=%CD% 36 | cd %~dp0 37 | 38 | REM Initialise error check value 39 | SET ERROR=0 40 | 41 | REM Check if executable can be located 42 | IF NOT EXIST "project_generate.exe" ( 43 | ECHO "Error: FFVS Project Generator executable file not found." 44 | IF EXIST "../.git" ( 45 | ECHO "Please build the executable using the supplied project before continuing." 46 | ) 47 | GOTO exitOnError 48 | ) 49 | 50 | REM Check if FFmpeg directory can be located 51 | SET SEARCHPATHS=(./, ../, ./ffmpeg/, ../ffmpeg/, ../../ffmpeg/, ../../../, ../../, ./source/ffmpeg, ../source/ffmpeg, ../../source/ffmpeg/) 52 | SET FFMPEGPATH= 53 | FOR %%I IN %SEARCHPATHS% DO ( 54 | IF EXIST "%%I/ffmpeg.h" ( 55 | SET FFMPEGPATH=%%I 56 | ) 57 | IF EXIST "%%I/fftools/ffmpeg.h" ( 58 | SET FFMPEGPATH=%%I 59 | ) 60 | ) 61 | IF "%FFMPEGPATH%"=="" ( 62 | ECHO Error: Failed finding FFmpeg source directory 63 | GOTO exitOnError 64 | ) ELSE ( 65 | ECHO Located FFmpeg source directory at "%FFMPEGPATH%" 66 | ECHO. 67 | ) 68 | 69 | REM Copy across the batch file used to auto get required dependencies 70 | CALL :makeGetDeps || GOTO exit 71 | 72 | REM Get/Update any used dependency libraries 73 | SET USERPROMPT=N 74 | SET /P USERPROMPT=Do you want to download/update the required dependency projects (Y/N)? 75 | IF /I "%USERPROMPT%"=="Y" ( 76 | ECHO. 77 | CALL :getDeps || GOTO exit 78 | ECHO Ensure that any dependency projects have been built using the supplied project within the dependencies ./SMP folder before continuing. 79 | ECHO Warning: Some used dependencies require a manual download. Consult the readme for instructions to install the following needed components: 80 | ECHO OpenGL 81 | PAUSE 82 | ) 83 | 84 | REM Run the executable 85 | ECHO Running project generator... 86 | project_generate.exe %PGOPTIONS% 87 | GOTO exit 88 | 89 | :makeGetDeps 90 | ECHO Creating project_get_dependencies.bat... 91 | FOR %%I IN %DEPENDENCIES% DO SET LASTDEP=%%I 92 | MKDIR "%FFMPEGPATH%/SMP" >NUL 2>&1 93 | ( 94 | ECHO @ECHO OFF 95 | ECHO SETLOCAL EnableDelayedExpansion 96 | ECHO. 97 | ECHO SET UPSTREAMURL=%UPSTREAMURL% 98 | ECHO SET DEPENDENCIES=( ^^ 99 | FOR %%I IN %DEPENDENCIES% DO ( 100 | IF "%%I"=="%LASTDEP%" ( 101 | ECHO %%I ^^ 102 | ) ELSE ( 103 | ECHO %%I, ^^ 104 | ) 105 | ) 106 | type smp_project_get_dependencies 107 | ) > "%FFMPEGPATH%/SMP/project_get_dependencies.bat" 108 | ECHO. 109 | EXIT /B %ERRORLEVEL% 110 | 111 | :getDeps 112 | REM Add current repo to list of already passed dependencies 113 | ECHO Getting and updating any required dependency libs... 114 | cd "%FFMPEGPATH%/SMP" 115 | CALL project_get_dependencies.bat "ffmpeg" || EXIT /B 1 116 | cd %~dp0 117 | ECHO. 118 | EXIT /B %ERRORLEVEL% 119 | 120 | :exitOnError 121 | SET ERROR=1 122 | 123 | :exit 124 | REM Check if this was launched from an existing terminal or directly from .bat 125 | REM If launched by executing the .bat then pause on completion 126 | cd %CURRDIR% 127 | ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1 128 | IF %ERRORLEVEL% == 0 IF "%~1"=="" PAUSE 129 | EXIT /B %ERROR% 130 | -------------------------------------------------------------------------------- /bin/smp_project_generate_noredist.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET UPSTREAMURL=https://github.com/ShiftMediaProject 4 | SET DEPENDENCIES=( ^ 5 | bzip2, ^ 6 | fdk-aac, ^ 7 | fontconfig, ^ 8 | freetype2, ^ 9 | fribidi, ^ 10 | game-music-emu, ^ 11 | gnutls, ^ 12 | harfbuzz, ^ 13 | lame, ^ 14 | libass, ^ 15 | libbluray, ^ 16 | libcdio, ^ 17 | libcdio-paranoia, ^ 18 | libiconv, ^ 19 | libilbc, ^ 20 | libgcrypt, ^ 21 | liblzma, ^ 22 | libssh, ^ 23 | libxml2, ^ 24 | libvpx, ^ 25 | mfx_dispatch, ^ 26 | modplug, ^ 27 | opus, ^ 28 | sdl, ^ 29 | soxr, ^ 30 | speex, ^ 31 | theora, ^ 32 | vorbis, ^ 33 | x264, ^ 34 | x265, ^ 35 | xvid, ^ 36 | zlib ^ 37 | ) 38 | SET PGOPTIONS=--enable-gpl --enable-version3 --enable-nonfree --enable-bzlib --enable-iconv --enable-lzma --enable-sdl2 --enable-zlib --enable-libmp3lame --enable-libvorbis --enable-libspeex --enable-libopus --enable-libilbc --enable-libtheora --enable-libx264 --enable-libx265 --enable-libxvid --enable-libvpx --enable-libgme --enable-libmodplug --enable-libsoxr --enable-libfreetype --enable-fontconfig --enable-libfribidi --enable-libharfbuzz --enable-libass --enable-libxml2 --enable-gnutls --disable-schannel --enable-gcrypt --enable-libssh --enable-libcdio --enable-libbluray --enable-libdvdread --enable-libdvdnav --enable-opengl --enable-libmfx --enable-ffnvcodec --enable-cuda --enable-amf --enable-libfdk-aac --enable-vulkan 39 | 40 | REM Store current directory and ensure working directory is the location of current .bat 41 | SET CURRDIR=%CD% 42 | cd %~dp0 43 | 44 | REM Initialise error check value 45 | SET ERROR=0 46 | 47 | REM Check if executable can be located 48 | IF NOT EXIST "project_generate.exe" ( 49 | ECHO "Error: FFVS Project Generator executable file not found." 50 | IF EXIST "../.git" ( 51 | ECHO "Please build the executable using the supplied project before continuing." 52 | ) 53 | GOTO exitOnError 54 | ) 55 | 56 | REM Check if FFmpeg directory can be located 57 | SET SEARCHPATHS=(./, ../, ./ffmpeg/, ../ffmpeg/, ../../ffmpeg/, ../../../, ../../, ./source/ffmpeg, ../source/ffmpeg, ../../source/ffmpeg/) 58 | SET FFMPEGPATH= 59 | FOR %%I IN %SEARCHPATHS% DO ( 60 | IF EXIST "%%I/ffmpeg.h" ( 61 | SET FFMPEGPATH=%%I 62 | ) 63 | IF EXIST "%%I/fftools/ffmpeg.h" ( 64 | SET FFMPEGPATH=%%I 65 | ) 66 | ) 67 | IF "%FFMPEGPATH%"=="" ( 68 | ECHO Error: Failed finding FFmpeg source directory 69 | GOTO exitOnError 70 | ) ELSE ( 71 | ECHO Located FFmpeg source directory at "%FFMPEGPATH%" 72 | ECHO. 73 | ) 74 | 75 | REM Copy across the batch file used to auto get required dependencies 76 | CALL :makeGetDeps || GOTO exit 77 | 78 | REM Get/Update any used dependency libraries 79 | SET USERPROMPT=N 80 | SET /P USERPROMPT=Do you want to download/update the required dependency projects (Y/N)? 81 | IF /I "%USERPROMPT%"=="Y" ( 82 | ECHO. 83 | CALL :getDeps || GOTO exit 84 | ECHO Ensure that any dependency projects have been built using the supplied project within the dependencies ./SMP folder before continuing. 85 | ECHO Warning: Some used dependencies require a manual download. Consult the readme for instructions to install the following needed components: 86 | ECHO OpenGL, CUDA 87 | PAUSE 88 | ) 89 | 90 | REM Run the executable 91 | ECHO Running project generator... 92 | project_generate.exe %PGOPTIONS% 93 | GOTO exit 94 | 95 | :makeGetDeps 96 | ECHO Creating project_get_dependencies.bat... 97 | FOR %%I IN %DEPENDENCIES% DO SET LASTDEP=%%I 98 | MKDIR "%FFMPEGPATH%/SMP" >NUL 2>&1 99 | ( 100 | ECHO @ECHO OFF 101 | ECHO SETLOCAL EnableDelayedExpansion 102 | ECHO. 103 | ECHO SET UPSTREAMURL=%UPSTREAMURL% 104 | ECHO SET DEPENDENCIES=( ^^ 105 | FOR %%I IN %DEPENDENCIES% DO ( 106 | IF "%%I"=="%LASTDEP%" ( 107 | ECHO %%I ^^ 108 | ) ELSE ( 109 | ECHO %%I, ^^ 110 | ) 111 | ) 112 | type smp_project_get_dependencies 113 | ) > "%FFMPEGPATH%/SMP/project_get_dependencies.bat" 114 | ECHO. 115 | EXIT /B %ERRORLEVEL% 116 | 117 | :getDeps 118 | REM Add current repo to list of already passed dependencies 119 | ECHO Getting and updating any required dependency libs... 120 | cd "%FFMPEGPATH%/SMP" 121 | CALL project_get_dependencies.bat "ffmpeg" || EXIT /B 1 122 | cd %~dp0 123 | ECHO. 124 | EXIT /B %ERRORLEVEL% 125 | 126 | :exitOnError 127 | SET ERROR=1 128 | 129 | :exit 130 | REM Check if this was launched from an existing terminal or directly from .bat 131 | REM If launched by executing the .bat then pause on completion 132 | cd %CURRDIR% 133 | ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1 134 | IF %ERRORLEVEL% == 0 IF "%~1"=="" PAUSE 135 | EXIT /B %ERROR% -------------------------------------------------------------------------------- /bin/smp_project_get_dependencies: -------------------------------------------------------------------------------- 1 | ) 2 | 3 | REM Get passed in list of dependencies to skip 4 | SET PASSDEPENDENCIES=%~1 5 | 6 | REM Check if git is installed and available 7 | IF "%MSVC_VER%"=="" ( 8 | git status >NUL 2>&1 9 | IF ERRORLEVEL 1 ( 10 | ECHO A working copy of git was not found. To use this script you must first install git for windows. 11 | GOTO exitOnError 12 | ) 13 | ) 14 | 15 | REM Store current directory and ensure working directory is the location of current .bat 16 | SET CURRDIR="%CD%" 17 | cd "%~dp0" 18 | 19 | REM Initialise error check value 20 | SET ERROR=0 21 | 22 | cd ..\.. 23 | FOR %%I IN %DEPENDENCIES% DO ( 24 | ECHO !PASSDEPENDENCIES! | FINDSTR /C:"%%I" >NUL 2>&1 || ( 25 | REM Check if MSVC_VER environment variable is set 26 | IF "%MSVC_VER%"=="" ( 27 | CALL :cloneOrUpdateRepo "%%I" || GOTO exitOnError 28 | ) ELSE ( 29 | CALL :downloadLibs "%%I" || GOTO exitOnError 30 | ) 31 | ) 32 | ) 33 | cd "%CURRDIR%" >NUL 34 | GOTO exit 35 | 36 | REM Function to clone or update a repo 37 | REM cloneOrUpdateRepo: RepoName 38 | REM RepoName = Name of the repository 39 | :cloneOrUpdateRepo 40 | SET REPONAME=%~1 41 | REM Check if the repo folder already exists 42 | IF EXIST "%REPONAME%" ( 43 | ECHO %REPONAME%: Existing folder found. Checking for updates... 44 | cd %REPONAME% 45 | REM Check if any updates are available 46 | FOR /f %%J IN ('git rev-parse HEAD') do set CURRHEAD=%%J 47 | FOR /f %%J IN ('git ls-remote origin HEAD') do set ORIGHEAD=%%J 48 | IF "!CURRHEAD!"=="!ORIGHEAD!" ( 49 | ECHO %REPONAME%: Repository up to date. 50 | ) ELSE ( 51 | REM Stash any uncommited changes then update from origin 52 | ECHO %REPONAME%: Updates available. Updating repository... 53 | git checkout master --quiet 54 | git stash --quiet 55 | git pull origin master --quiet -ff 56 | git stash pop --quiet 57 | ) 58 | cd ..\ 59 | ) ELSE ( 60 | ECHO %REPONAME%: Existing folder not found. Cloning repository... 61 | REM Clone from the origin repo 62 | SET REPOURL=%UPSTREAMURL%/%REPONAME%.git 63 | git clone !REPOURL! --quiet 64 | IF ERRORLEVEL 1 ( 65 | ECHO %REPONAME%: Git clone failed. 66 | GOTO exitOnError 67 | ) 68 | REM Initialise autocrlf options to fix cross platform interoperation 69 | REM Once updated the repo needs to be reset to correct the local line endings 70 | cd %REPONAME% 71 | git config --local core.autocrlf false 72 | git rm --cached --ignore-unmatch -r . --quiet 73 | git reset --hard --quiet 74 | cd ..\ 75 | ) 76 | REM Add current repo to list of already passed dependencies 77 | SET PASSDEPENDENCIES=%PASSDEPENDENCIES% %REPONAME% 78 | REM Check if the repo itself has required dependencies 79 | IF EXIST "%REPONAME%\SMP\project_get_dependencies.bat" ( 80 | ECHO %REPONAME%: Found additional dependencies... 81 | ECHO. 82 | cd %REPONAME%\SMP 83 | project_get_dependencies.bat "!PASSDEPENDENCIES!" || EXIT /B 1 84 | cd ..\.. 85 | ) 86 | ECHO. 87 | EXIT /B %ERRORLEVEL% 88 | 89 | REM Function to download existing prebuilt libraries 90 | REM downloadLibs: RepoName 91 | REM RepoName = Name of the repository 92 | :downloadLibs 93 | SET REPONAME=%~1 94 | REM Get latest release 95 | ECHO %REPONAME%: Getting latest release... 96 | SET UPSTREAMAPIURL=%UPSTREAMURL:github.com=api.github.com/repos% 97 | REM Check if secure OAuth is available 98 | IF "%GITHUBTOKEN%" == "" ( 99 | powershell -nologo -noprofile -command "$currentMaxTls = [Math]::Max([Net.ServicePointManager]::SecurityProtocol.value__,[Net.SecurityProtocolType]::Tls.value__);$newTlsTypes = [enum]::GetValues('Net.SecurityProtocolType') | ?{ $_ -gt $currentMaxTls };ForEach ($newTls in $newTlsTypes) { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor $newTls };try { Invoke-RestMethod -Uri %UPSTREAMAPIURL%/%REPONAME%/releases/latest > latest.json } catch {exit 1}" 100 | ) ELSE ( 101 | powershell -nologo -noprofile -command "$currentMaxTls = [Math]::Max([Net.ServicePointManager]::SecurityProtocol.value__,[Net.SecurityProtocolType]::Tls.value__);$newTlsTypes = [enum]::GetValues('Net.SecurityProtocolType') | ?{ $_ -gt $currentMaxTls };ForEach ($newTls in $newTlsTypes) { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor $newTls };try { Invoke-RestMethod -Uri %UPSTREAMAPIURL%/%REPONAME%/releases/latest -Headers @{'Authorization' = 'token %GITHUBTOKEN%'} > latest.json } catch {exit 1}" 102 | ) 103 | IF ERRORLEVEL 1 ( ECHO Failed getting latest %REPONAME% release & EXIT /B 1 ) 104 | REM Get tag for latest release 105 | FOR /F "tokens=* USEBACKQ" %%F IN (`TYPE latest.json ^| FINDSTR /B "tag_name"`) DO SET TAG=%%F 106 | FOR /F "tokens=2 delims=: " %%F in ("%TAG%") DO SET TAG=%%F 107 | IF "%TAG%"=="" ( ECHO Failed getting latest %REPONAME% release tag information & EXIT /B 1 ) 108 | REM Get download name of latest release 109 | SET LIBNAME= 110 | FOR /F "tokens=* USEBACKQ" %%F IN (`TYPE latest.json ^| FINDSTR "name="`) DO ( SET TEMPF=%%F 111 | SET TEMPF=!TEMPF:*name=! 112 | IF "!TEMPF:~1,3!"=="lib" ( SET LIBNAME=!TEMPF:~1! ) 113 | ) 114 | FOR /F "tokens=1 delims=_" %%F in ("%LIBNAME%") DO SET LIBNAME=%%F 115 | IF "%LIBNAME%"=="" ( ECHO Failed getting latest %REPONAME% release name information & EXIT /B 1 ) 116 | DEL /F /Q latest.json 117 | REM Get the download location for the required tag 118 | SET TAG2=%TAG:+=.% 119 | SET DLURL=%UPSTREAMURL%/%REPONAME%/releases/download/%TAG%/%LIBNAME%_%TAG2%_msvc%MSVC_VER%.zip 120 | REM Download a pre-built archive and extract 121 | ECHO %REPONAME%: Downloading %LIBNAME%_%TAG%_msvc%MSVC_VER%.zip... 122 | SET PREBUILTDIR=prebuilt 123 | MKDIR %PREBUILTDIR% >NUL 2>&1 124 | powershell -nologo -noprofile -command "$currentMaxTls = [Math]::Max([Net.ServicePointManager]::SecurityProtocol.value__,[Net.SecurityProtocolType]::Tls.value__);$newTlsTypes = [enum]::GetValues('Net.SecurityProtocolType') | ?{ $_ -gt $currentMaxTls };ForEach ($newTls in $newTlsTypes) { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor $newTls };try { (New-Object Net.WebClient).DownloadFile('%DLURL%', '%PREBUILTDIR%\temp.zip') } catch {exit 1}" 125 | IF ERRORLEVEL 1 ( ECHO Failed downloading %DLURL% & EXIT /B 1 ) 126 | powershell -nologo -noprofile -command "Add-Type -AssemblyName System.IO.Compression.FileSystem; $zip=[System.IO.Compression.ZipFile]::OpenRead('%PREBUILTDIR%\temp.zip'); foreach ($item in $zip.Entries) { try {$file=(Join-Path -Path .\%PREBUILTDIR% -ChildPath $item.FullName); $null=[System.IO.Directory]::CreateDirectory((Split-Path -Path $file)); [System.IO.Compression.ZipFileExtensions]::ExtractToFile($item,$file,$true)} catch {exit 1} }" 127 | IF ERRORLEVEL 1 ( ECHO Failed extracting downloaded archive & EXIT /B 1 ) 128 | DEL /F /Q %PREBUILTDIR%\\temp.zip 129 | ECHO. 130 | EXIT /B %ERRORLEVEL% 131 | 132 | :exitOnError 133 | cd "%CURRDIR%" 134 | SET ERROR=1 135 | 136 | :exit 137 | REM Directly exit if an AppVeyor build 138 | IF NOT "%APPVEYOR%"=="" ( 139 | GOTO return 140 | ) 141 | REM Return the passed dependency list 142 | ( 143 | ENDLOCAL 144 | SET PASSDEPENDENCIES=%PASSDEPENDENCIES% 145 | ) 146 | 147 | REM Check if this was launched from an existing terminal or directly from .bat 148 | REM If launched by executing the .bat then pause on completion 149 | ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1 150 | IF %ERRORLEVEL% == 0 IF "%~1"=="" PAUSE 151 | 152 | :return 153 | EXIT /B %ERROR% 154 | 155 | -------------------------------------------------------------------------------- /include/configGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2014 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef CONFIGGENERATOR_H 22 | #define CONFIGGENERATOR_H 23 | 24 | #include "helperFunctions.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | class ConfigGenerator 31 | { 32 | friend class ProjectGenerator; 33 | 34 | private: 35 | class ConfigPair 36 | { 37 | friend class ConfigGenerator; 38 | friend class ProjectGenerator; 39 | 40 | private: 41 | string m_option; 42 | string m_prefix; 43 | string m_value; 44 | bool m_lock; 45 | 46 | ConfigPair(string option, string prefix, string value) 47 | : m_option(std::move(option)) 48 | , m_prefix(std::move(prefix)) 49 | , m_value(std::move(value)) 50 | , m_lock(false) 51 | {} 52 | }; 53 | 54 | using ValuesList = vector; 55 | using DefaultValuesList = map; 56 | using DependencyList = map; 57 | using ConfigList = map>; 58 | using InterDependencies = map, vector>>>; 59 | 60 | ValuesList m_fixedConfigValues; 61 | ValuesList m_configValues; 62 | uint m_configComponentsStart{0}; 63 | uint m_configValuesEnd{0}; 64 | string m_configureFile; 65 | bool m_isLibav{false}; 66 | string m_projectName; 67 | string m_rootDirectory; 68 | string m_solutionDirectory; 69 | string m_outDirectory; 70 | bool m_onlyDCE{false}; 71 | bool m_usingExistingConfig{false}; 72 | DefaultValuesList m_replaceList; 73 | DefaultValuesList m_replaceListASM; 74 | bool m_useNASM{true}; 75 | ConfigList m_cachedConfigLists; 76 | 77 | public: 78 | /** Default constructor. */ 79 | ConfigGenerator(); 80 | 81 | /** 82 | * Pass configuration options based on input values. 83 | * @param argc The number of input options. 84 | * @param [in] argv If non-null, the the list of input options. 85 | * @return True if it succeeds, false if it fails. 86 | */ 87 | bool passConfig(int argc, char** argv); 88 | 89 | /** 90 | * Outputs a new configurations files based on current internal settings. 91 | * @return True if it succeeds, false if it fails. 92 | */ 93 | bool outputConfig(); 94 | 95 | /** Deletes any files that may have been previously created by outputConfig. */ 96 | void deleteCreatedFiles() const; 97 | 98 | private: 99 | /** 100 | * Passes the configure file and loads all available options. 101 | * @return True if it succeeds, false if it fails. 102 | */ 103 | bool passConfigureFile(); 104 | 105 | /** 106 | * Passes an existing config.h file. 107 | * @return True if it succeeds, false if it fails. 108 | */ 109 | bool passExistingConfig(); 110 | 111 | /** 112 | * Change configuration options. 113 | * @param option The option to change. 114 | * @return True if it succeeds, false if it fails. 115 | */ 116 | bool changeConfig(const string& option); 117 | 118 | /** 119 | * Checks current config values and performs validation of requirements. 120 | * @return True if it succeeds, false if it fails. 121 | */ 122 | bool passCurrentValues(); 123 | 124 | /** 125 | * Makes a files path relative to the project directory. 126 | * @remark Assumes input file path is relative to the generator. 127 | * @param fileName Filename of the file. 128 | * @param [out] retFileName Filename with the path modified. 129 | */ 130 | void makeFileProjectRelative(const string& fileName, string& retFileName) const; 131 | 132 | /** 133 | * Makes a files path relative to the generator directory. 134 | * @remark Assumes input file path is relative to the project. 135 | * @param fileName Filename of the file. 136 | * @param [out] retFileName Filename with the path modified. 137 | */ 138 | void makeFileGeneratorRelative(const string& fileName, string& retFileName) const; 139 | 140 | static void buildFixedValues(DefaultValuesList& fixedValues); 141 | 142 | /** 143 | * Builds a list of configuration options that need to be replaced with the returned values. 144 | * @param [in,out] replaceValues The replace values for config.h. 145 | * @param [in,out] header The header that must be output at top of config file. 146 | * @param [in,out] replaceValuesASM The replace values for config.asm. 147 | */ 148 | void buildReplaceValues(DefaultValuesList& replaceValues, string& header, DefaultValuesList& replaceValuesASM); 149 | 150 | /** 151 | * Creates a list of config items that are automatically set and should be be set by the user. 152 | * @param [out] reservedItems The reserved items. 153 | */ 154 | static void buildReservedValues(vector& reservedItems); 155 | 156 | /** 157 | * Creates a list of additional config option dependencies that are not available as actual config options. 158 | * @param [out] additionalDependencies The additional dependencies. 159 | */ 160 | void buildAdditionalDependencies(DependencyList& additionalDependencies) const; 161 | 162 | /** 163 | * Creates a list of additional dependencies between config options (in addition to _deps lists). 164 | * @param [out] interDependencies The additional dependencies. Format is >> 166 | */ 167 | void buildInterDependencies(InterDependencies& interDependencies); 168 | 169 | /** 170 | * Creates a list of components that can be disabled based on the current configuration as better alternatives are 171 | * enabled. 172 | * @param [in,out] optimisedDisables The optimised disables. 173 | */ 174 | static void buildOptimisedDisables(ConfigList& optimisedDisables); 175 | 176 | /** 177 | * Creates a list of config options that must be forced to be enabled if the specified option is enabled. 178 | * @param optionLower The enabled option (in lower case). 179 | * @param [in,out] forceEnable The forced enable options. 180 | */ 181 | void buildForcedEnables(const string& optionLower, vector& forceEnable); 182 | 183 | /** 184 | * Creates a list of config options that must be forced to be disabled if the specified option is disabled. 185 | * @param optionLower The disabled option (in lower case). 186 | * @param [in,out] forceDisable The forced disable options. 187 | */ 188 | void buildForcedDisables(const string& optionLower, vector& forceDisable); 189 | 190 | /** 191 | * Creates a list of command line arguments that must be handled before all others. 192 | * @param [out] earlyArgs The early arguments. 193 | */ 194 | static void buildEarlyConfigArgs(vector& earlyArgs); 195 | 196 | void buildObjects(const string& tag, vector& objects); 197 | 198 | bool getConfigList( 199 | const string& list, vector& returnList, bool force = true, uint currentFilePos = string::npos); 200 | 201 | /** 202 | * Perform the equivalent of configures find_things function. 203 | * @param param1 The first parameter. 204 | * @param param2 The second parameter. 205 | * @param param3 The third parameter. 206 | * @param [in,out] returnList Returns any detected configure defines. 207 | * @param [in,out] returnExterns (Optional) If non-null, returns any detected extern variables. 208 | * @return True if it succeeds, false if it fails. 209 | */ 210 | bool passFindThings(const string& param1, const string& param2, const string& param3, vector& returnList, 211 | vector* returnExterns = nullptr) const; 212 | 213 | /** 214 | * Perform the equivalent of configures find_things_extern function. 215 | * @param param1 The first parameter. 216 | * @param param2 The second parameter. 217 | * @param param3 The third parameter. 218 | * @param param4 The fourth parameter. 219 | * @param [in,out] returnList Returns any detected configure defines. 220 | * @return True if it succeeds, false if it fails. 221 | */ 222 | bool passFindThingsExtern(const string& param1, const string& param2, const string& param3, const string& param4, 223 | vector& returnList) const; 224 | 225 | /** 226 | * Perform the equivalent of configures find_filters_extern function. 227 | * @param param1 The first parameter. 228 | * @param [in,out] returnList Returns any detected configure defines. 229 | * @return True if it succeeds, false if it fails. 230 | */ 231 | bool passFindFiltersExtern(const string& param1, vector& returnList) const; 232 | 233 | bool passAddSuffix( 234 | const string& param1, const string& param2, vector& returnList, uint currentFilePos = string::npos); 235 | 236 | bool passFilterOut(const string& param1, const string& param2, vector& returnList, uint currentFilePos); 237 | 238 | /** 239 | * Perform the equivalent of configures full_filter_name function. 240 | * @param param1 The first parameter. 241 | * @param [in,out] returnString The return. 242 | * @return True if it succeeds, false if it fails. 243 | */ 244 | bool passFullFilterName(const string& param1, string& returnString) const; 245 | 246 | bool passConfigList(const string& prefix, const string& suffix, const string& list); 247 | 248 | bool passEnabledComponents(const string& file, const string& structName, const string& name, const string& list); 249 | 250 | /** 251 | * Sets up all default starting config values. 252 | * @return True if it succeeds, false if it fails. 253 | */ 254 | bool buildDefaultValues(); 255 | 256 | bool buildAutoDetectValues(); 257 | 258 | /** 259 | * Sets up all config values that have a forced value. 260 | * @return True if it succeeds, false if it fails. 261 | */ 262 | bool buildForcedValues(); 263 | 264 | /** 265 | * Update configuration option without performing any dependency option checks. 266 | * @param option The option to update. 267 | * @param enable True to enable, false to disable. 268 | * @param weak (Optional) True to only change a value if it is not already set. 269 | * @returns True if it succeeds, false if it fails. 270 | */ 271 | bool fastToggleConfigValue(const string& option, bool enable, bool weak = false); 272 | 273 | /** 274 | * Update configuration option and perform any dependency option updates as well. 275 | * @param option The option to update. 276 | * @param enable True to enable, false to disable. 277 | * @param weak (Optional) True to only change a value if it is not already set. 278 | * @param deep (Optional) True to also enable _select and _suggest dependencies. 279 | * @param recursive (Optional) True if the function has been called from within itself. 280 | * @returns True if it succeeds, false if it fails. 281 | */ 282 | bool toggleConfigValue( 283 | const string& option, bool enable, bool weak = false, bool deep = false, bool recursive = false); 284 | 285 | /** 286 | * Gets configuration option. 287 | * @param option The options name. 288 | * @return The configuration option, m_configValues.end() if option not found. 289 | */ 290 | ValuesList::iterator getConfigOption(const string& option); 291 | 292 | ValuesList::const_iterator getConfigOption(const string& option) const; 293 | 294 | /** 295 | * Gets configuration option with prefix (i.e. HAVE_, CONFIG_ etc.) included. 296 | * @param option The options name. 297 | * @return The configuration option, m_configValues.end() if option not found. 298 | */ 299 | ValuesList::iterator getConfigOptionPrefixed(const string& option); 300 | 301 | ValuesList::const_iterator getConfigOptionPrefixed(const string& option) const; 302 | 303 | /** 304 | * Queries if a configuration option is enabled. 305 | * @param option The option. 306 | * @return True if the configuration option is enabled, false if not. 307 | */ 308 | bool isConfigOptionEnabled(const string& option) const; 309 | 310 | /** 311 | * Queries if a configuration option exists. 312 | * @param option The option. 313 | * @return True if the configuration option is valid, false if not. 314 | */ 315 | bool isConfigOptionValid(const string& option) const; 316 | 317 | /** 318 | * Queries if a configuration option with prefix (i.e. HAVE_, CONFIG_ etc.) exists. 319 | * @param option The option. 320 | * @return True if the configuration option is valid, false if not. 321 | */ 322 | bool isConfigOptionValidPrefixed(const string& option) const; 323 | 324 | /** 325 | * Queries if assembly is enabled. 326 | * @return True if asm is enabled, false if not. 327 | */ 328 | bool isASMEnabled() const; 329 | 330 | /** 331 | * Queries if cuda is enabled. 332 | * @returns True if cuda is enabled, false if not. 333 | */ 334 | bool isCUDAEnabled() const; 335 | 336 | /** 337 | * Queries if opencl compilation is enabled. 338 | * @returns True if opencl is enabled, false if not. 339 | */ 340 | bool isOpenCLEnabled() const; 341 | 342 | /** 343 | * Queries if spirv compilation is enabled. 344 | * @returns True if spirv is enabled, false if not. 345 | */ 346 | bool isSPIRVEnabled() const; 347 | 348 | /** 349 | * Gets minimum supported windows version from config file. 350 | * @param [out] major The version number major. 351 | * @param [out] minor The version number minor. 352 | * @return True if it succeeds, false if it fails. 353 | */ 354 | bool getMinWindowsVersion(uint& major, uint& minor) const; 355 | 356 | bool passDependencyCheck(const ValuesList::iterator& option); 357 | }; 358 | 359 | #endif 360 | -------------------------------------------------------------------------------- /include/helperFunctions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2015 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _HELPERFUNCTIONS_H_ 22 | #define _HELPERFUNCTIONS_H_ 23 | 24 | #include 25 | #include 26 | 27 | using namespace std; 28 | 29 | #if defined(__x86_64) || defined(_M_X64) 30 | typedef unsigned __int64 uint; 31 | #else 32 | using uint = unsigned int; 33 | #endif 34 | 35 | namespace project_generate { 36 | /** 37 | * Loads from a file. 38 | * @param fileName Filename of the file. 39 | * @param [out] retString The returned string containing file contents. 40 | * @param binary (Optional) True to read in binary mode. 41 | * @param outError (Optional) True to output any detected errors. 42 | * @return True if it succeeds, false if it fails. 43 | */ 44 | bool loadFromFile(const string& fileName, string& retString, bool binary = false, bool outError = true); 45 | 46 | /** 47 | * Loads from an internal embedded resource. 48 | * @param resourceID Identifier for the resource. 49 | * @param [out] retString The returned string containing the loaded resource. 50 | * @return True if it succeeds, false if it fails. 51 | */ 52 | bool loadFromResourceFile(int resourceID, string& retString); 53 | 54 | /** 55 | * Writes to file. 56 | * @param fileName Filename of the file. 57 | * @param inString The inString to write. 58 | * @param binary (Optional) True to write in binary mode (in normal text mode line ending are converted to OS 59 | * specific). 60 | * @return True if it succeeds, false if it fails. 61 | */ 62 | bool writeToFile(const string& fileName, const string& inString, bool binary = false); 63 | 64 | /** 65 | * Copies an internal embedded resource to a file. 66 | * @param resourceID Identifier for the resource. 67 | * @param destinationFile Destination file. 68 | * @param binary (Optional) True to write in binary mode (in normal text mode line ending are converted to 69 | * OS specific). 70 | * @return True if it succeeds, false if it fails. 71 | */ 72 | bool copyResourceFile(int resourceID, const string& destinationFile, bool binary = false); 73 | 74 | /** 75 | * Deletes s file. 76 | * @param destinationFile Pathname of the file to delete. 77 | */ 78 | void deleteFile(const string& destinationFile); 79 | 80 | /** 81 | * Deletes a folder. 82 | * @param destinationFolder Pathname of the folder to delete. 83 | */ 84 | void deleteFolder(const string& destinationFolder); 85 | 86 | /** 87 | * Queries if a folder is empty. 88 | * @param folder Pathname of the folder. 89 | * @return True if the folder is empty, false if not. 90 | */ 91 | bool isFolderEmpty(const string& folder); 92 | 93 | /** 94 | * Copies a file. 95 | * @param sourceFolder Pathname of the source folder. 96 | * @param destinationFolder Pathname of the destination folder. 97 | * @return True if it succeeds, false if it fails. 98 | */ 99 | bool copyFile(const string& sourceFolder, const string& destinationFolder); 100 | 101 | /** 102 | * Gets default copywrite header. 103 | * @param decription The description of the current file to add to the header. 104 | * @return The copywrite header. 105 | */ 106 | string getCopywriteHeader(const string& decription); 107 | 108 | /** 109 | * Makes a directory. 110 | * @param directory Pathname of the directory. 111 | * @return True if it succeeds, false if it fails. 112 | */ 113 | bool makeDirectory(const string& directory); 114 | 115 | /** 116 | * Searches for the first file by name (supports wildcards). 117 | * @param fileName The file name to search for. 118 | * @param [out] retFileName Filename of the found file. 119 | * @return True if it succeeds, false if it fails. 120 | */ 121 | bool findFile(const string& fileName, string& retFileName); 122 | 123 | /** 124 | * Searches for files by name (supports wildcards). 125 | * @param fileSearch The file name to search for. 126 | * @param [in,out] retFiles The returned list of found files. 127 | * @param recursive (Optional) True to process any sub-directories. 128 | * @return True if it succeeds, false if it fails. 129 | */ 130 | bool findFiles(const string& fileSearch, vector& retFiles, bool recursive = true); 131 | 132 | /** 133 | * Searches for folders by name (supports wildcards). 134 | * @param folderSearch The folder name to search for. 135 | * @param [in,out] retFolders The returned list of found folders. 136 | * @param recursive (Optional) True to process any sub-directories. 137 | * @return True if it succeeds, false if it fails. 138 | */ 139 | bool findFolders(const string& folderSearch, vector& retFolders, bool recursive = true); 140 | 141 | /** 142 | * Makes a file path relative to another. 143 | * @param path Input path. 144 | * @param makeRelativeTo The path to make relative to. 145 | * @param [out] retPath The returned path. 146 | */ 147 | void makePathsRelative(const string& path, const string& makeRelativeTo, string& retPath); 148 | 149 | /** 150 | * Removes all whitespace from a string in place. 151 | * @param [in,out] inputString The string to operate on. 152 | */ 153 | void removeWhiteSpace(string& inputString); 154 | 155 | /** 156 | * Searches through a string and replaces all occurrences of the search tag in place. 157 | * @param [in,out] inString The string to perform find and replace operation on. 158 | * @param search The search string. 159 | * @param replace The string used for replacement. 160 | */ 161 | void findAndReplace(string& inString, const string& search, const string& replace); 162 | 163 | /** 164 | * Searches for the existence of an environment variable. 165 | * @param envVar The environment variable. 166 | * @return True if it succeeds, false if it fails. 167 | */ 168 | bool findEnvironmentVariable(const string& envVar); 169 | 170 | /** Press key to continue terminal prompt. */ 171 | void pressKeyToContinue(); 172 | 173 | /** 174 | * Output a single line of text. 175 | * @param message The message. 176 | */ 177 | void outputLine(const string& message); 178 | 179 | /** 180 | * Output information message. 181 | * @remark Whether this outputs depends on currently set verbosity. 182 | * @param message The message. 183 | * @param header (Optional) True to add the info starting header. 184 | */ 185 | void outputInfo(const string& message, bool header = true); 186 | 187 | /** 188 | * Output warning message. 189 | * @remark Whether this outputs depends on currently set verbosity. 190 | * @param message The message. 191 | * @param header (Optional) True to add the warning starting header. 192 | */ 193 | void outputWarning(const string& message, bool header = true); 194 | 195 | /** 196 | * Output error message. 197 | * @remark Whether this outputs depends on currently set verbosity. 198 | * @param message The message. 199 | * @param header (Optional) True to add the error starting header. 200 | */ 201 | void outputError(const string& message, bool header = true); 202 | 203 | enum Verbosity 204 | { 205 | VERBOSITY_INFO, // Info+Warning+Error 206 | VERBOSITY_WARNING, // Warning+Error 207 | VERBOSITY_ERROR, // Error 208 | }; 209 | 210 | /** 211 | * Sets output verbosity for output message functions. 212 | * @param verbose The verbosity to set. 213 | */ 214 | void setOutputVerbosity(Verbosity verbose); 215 | 216 | const string g_endLine = "\n\r\f\v"; 217 | const string g_whiteSpace = " \t" + g_endLine; 218 | const string g_operators = "+-*/=<>;()[]{}!^%|&~\'\"#?:"; 219 | const string g_nonName = g_operators + g_whiteSpace; 220 | const string g_preProcessor = "&|()!="; 221 | }; // namespace project_generate 222 | 223 | using namespace project_generate; 224 | 225 | #endif 226 | -------------------------------------------------------------------------------- /include/projectGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2014 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _PROJECTGENERATOR_H_ 22 | #define _PROJECTGENERATOR_H_ 23 | 24 | #include "configGenerator.h" 25 | 26 | #include 27 | #include 28 | 29 | class ProjectGenerator 30 | { 31 | private: 32 | using StaticList = vector; 33 | using UnknownList = map; 34 | struct ConfigConds 35 | { 36 | bool isStatic = false; 37 | bool isShared = false; 38 | bool is32 = false; 39 | bool is64 = false; 40 | 41 | ConfigConds(bool istatic, bool ishared, bool i32, bool i64) 42 | : isStatic(istatic) 43 | , isShared(ishared) 44 | , is32(i32) 45 | , is64(i64) 46 | {} 47 | }; 48 | using ConditionalList = map; 49 | ifstream m_inputFile; 50 | string m_inLine; 51 | StaticList m_includes; 52 | StaticList m_includesCPP; 53 | StaticList m_includesC; 54 | StaticList m_includesASM; 55 | ConditionalList m_includesConditionalCPP; 56 | ConditionalList m_includesConditionalC; 57 | ConditionalList m_includesConditionalASM; 58 | ConditionalList m_includesConditionalCU; 59 | ConditionalList m_includesConditionalCL; 60 | ConditionalList m_includesConditionalCOMP; 61 | StaticList m_includesH; 62 | StaticList m_includesRC; 63 | StaticList m_includesCU; 64 | StaticList m_includesCL; 65 | StaticList m_includesCOMP; 66 | UnknownList m_replaceIncludes; 67 | StaticList m_libs; 68 | UnknownList m_unknowns; 69 | string m_projectName; 70 | string m_projectDir; 71 | StaticList m_subDirs; 72 | 73 | map m_projectLibs; 74 | 75 | const string m_tempDirectory = "FFVSTemp/"; 76 | 77 | public: 78 | ConfigGenerator m_configHelper; 79 | 80 | /** 81 | * Checks all found Makefiles based on current configuration and generates project files and a solution files as 82 | * needed. 83 | * @return True if it succeeds, false if it fails. 84 | */ 85 | bool passAllMake(); 86 | 87 | /** Deletes any files that may have been created by previous runs. */ 88 | void deleteCreatedFiles(); 89 | 90 | /** 91 | * Error function to cleanly exit. 92 | * @param cleanupFiles (Optional) True to delete created files. 93 | */ 94 | void errorFunc(bool cleanupFiles = true); 95 | 96 | private: 97 | /** 98 | * Outputs a project file for the current project directory. 99 | * @return True if it succeeds, false if it fails. 100 | */ 101 | bool outputProject(); 102 | 103 | /** 104 | * Output a project file for a program (ffplay etc.). 105 | * @param destinationFile Destination project file. 106 | * @param destinationFilterFile Destination project filter file. 107 | * @return True if it succeeds, false if it fails. 108 | */ 109 | bool outputProgramProject(const string& destinationFile, const string& destinationFilterFile); 110 | 111 | /** Cleans up any used variables after a project file has been created. */ 112 | void outputProjectCleanup(); 113 | 114 | /** 115 | * Outputs a solution file (Also calls outputProgramProject for any programs). 116 | * @return True if it succeeds, false if it fails. 117 | */ 118 | bool outputSolution(); 119 | 120 | bool passStaticIncludeObject(uint& startPos, uint& endPos, StaticList& staticIncludes); 121 | 122 | bool passStaticIncludeLine(uint startPos, StaticList& staticIncludes); 123 | 124 | bool passStaticInclude(uint length, StaticList& staticIncludes); 125 | 126 | bool passDynamicIncludeObject(uint& startPos, uint& endPos, string& ident, StaticList& includes); 127 | 128 | bool passDynamicIncludeLine(uint startPos, string& ident, StaticList& includes); 129 | 130 | bool passDynamicInclude(uint length, StaticList& includes); 131 | 132 | /** 133 | * Pass a static source include line from current makefile that is wrapped in a reserved conditional. 134 | * @param condition The pre-processor condition applied to the current line. 135 | * @param list The file list to add any found files to when the condition evaluates to 'true'. 136 | * @param replace The file list to add any found files to when the condition is a reserved value. 137 | * @param offset The offset to start passing (used to separate different file tags). 138 | * @return True if it succeeds, false if it fails. 139 | */ 140 | bool passCondition(const string& condition, StaticList& list, UnknownList& replace, uint offset = 0); 141 | 142 | /** 143 | * Pass a dynamic source include line from current makefile that is wrapped in a reserved conditional. 144 | * @param condition The pre-processor condition applied to the current line. 145 | * @param list The file list to add any found files to when the condition evaluates to 'true'. 146 | * @param replace The file list to add any found files to when the condition is a reserved value. 147 | * @param offset The offset to start passing (used to separate different file tags). 148 | * @return True if it succeeds, false if it fails. 149 | */ 150 | bool passDCondition(const string& condition, StaticList& list, UnknownList& replace, uint offset = 0); 151 | 152 | /** 153 | * Pass a static source include line from current makefile. 154 | * @param condition (Optional) The pre-processor condition applied to the current line. 155 | * @return True if it succeeds, false if it fails. 156 | */ 157 | bool passCInclude(const string& condition = ""); 158 | 159 | /** 160 | * Pass a dynamic source include line from current makefile. 161 | * @param condition (Optional) The pre-processor condition applied to the current line. 162 | * @return True if it succeeds, false if it fails. 163 | */ 164 | bool passDCInclude(const string& condition = ""); 165 | 166 | /** 167 | * Pass a static asm include line from current makefile. 168 | * @param offset The offset to start passing (used to separate old yasm and x86asm). 169 | * @param condition (Optional) The pre-processor condition applied to the current line. 170 | * @return True if it succeeds, false if it fails. 171 | */ 172 | bool passASMInclude(uint offset, const string& condition = ""); 173 | 174 | /** 175 | * Pass a dynamic asm include line from current makefile. 176 | * @param offset The offset to start passing (used to separate old yasm and x86asm). 177 | * @param condition (Optional) The pre-processor condition applied to the current line. 178 | * @return True if it succeeds, false if it fails. 179 | */ 180 | bool passDASMInclude(uint offset, const string& condition = ""); 181 | 182 | /** 183 | * Pass a static mmx include line from current makefile. 184 | * @param condition (Optional) The pre-processor condition applied to the current line. 185 | * @return True if it succeeds, false if it fails. 186 | */ 187 | bool passMMXInclude(const string& condition = ""); 188 | 189 | /** 190 | * Pass a dynamic mmx include line from current makefile. 191 | * @param condition (Optional) The pre-processor condition applied to the current line. 192 | * @return True if it succeeds, false if it fails. 193 | */ 194 | bool passDMMXInclude(const string& condition = ""); 195 | 196 | /** 197 | * Pass a static header include line from current makefile. 198 | * @return True if it succeeds, false if it fails. 199 | */ 200 | bool passHInclude(uint cutPos = 7); 201 | 202 | /** 203 | * Pass a dynamic header include line from current makefile. 204 | * @return True if it succeeds, false if it fails. 205 | */ 206 | bool passDHInclude(); 207 | 208 | /** 209 | * Pass a static lib include line from current makefile. 210 | * @return True if it succeeds, false if it fails. 211 | */ 212 | bool passLibInclude(); 213 | 214 | /** 215 | * Pass a dynamic lib include line from current makefile. 216 | * @return True if it succeeds, false if it fails. 217 | */ 218 | bool passDLibInclude(); 219 | 220 | /** 221 | * Pass a static unknown type include line from current makefile. 222 | * @return True if it succeeds, false if it fails. 223 | */ 224 | bool passDUnknown(); 225 | 226 | /** 227 | * Pass a dynamic unknown type include line from current makefile. 228 | * @return True if it succeeds, false if it fails. 229 | */ 230 | bool passDLibUnknown(); 231 | 232 | /** 233 | * Pass a shared only dynamic source include line from current makefile. 234 | * @return True if it succeeds, false if it fails. 235 | */ 236 | bool passSharedDCInclude(); 237 | 238 | /** 239 | * Pass a shared only source include line from current makefile. 240 | * @return True if it succeeds, false if it fails. 241 | */ 242 | bool passSharedCInclude(); 243 | 244 | /** 245 | * Pass a static only dynamic source include line from current makefile. 246 | * @return True if it succeeds, false if it fails. 247 | */ 248 | bool passStaticDCInclude(); 249 | 250 | /** 251 | * Pass a static only source include line from current makefile. 252 | * @return True if it succeeds, false if it fails. 253 | */ 254 | bool passStaticCInclude(); 255 | 256 | /** 257 | * Passes the makefile for the current project directory. 258 | * @return True if it succeeds, false if it fails. 259 | */ 260 | bool passMake(); 261 | 262 | /** 263 | * Pass the makefile for a specified program. 264 | * @return True if it succeeds, false if it fails. 265 | */ 266 | bool passProgramMake(); 267 | 268 | /** 269 | * Searches for the first source file. 270 | * @param file The file name. 271 | * @param extension The file extension. 272 | * @param [out] retFileName Filename of the found file. 273 | * @return True if it succeeds, false if it fails. 274 | */ 275 | bool findSourceFile(const string& file, const string& extension, string& retFileName) const; 276 | 277 | /** 278 | * Searches for matching source files. 279 | * @param file The file name. 280 | * @param extension The file extension. 281 | * @param [in,out] retFiles The returned list of matching files. 282 | * @return True if it succeeds, false if it fails. 283 | */ 284 | bool findSourceFiles(const string& file, const string& extension, vector& retFiles) const; 285 | 286 | void buildInterDependenciesHelper( 287 | const StaticList& configOptions, const StaticList& addDeps, StaticList& libs) const; 288 | 289 | void buildInterDependencies(StaticList& libs); 290 | 291 | /** 292 | * Gets library dependency lists. 293 | * @param [in,out] libs The project dependency libs. 294 | * @param [in,out] addLibs The windows dependency libs. 295 | * @param winrt True if checking for winrt. 296 | */ 297 | void buildDependencies(StaticList& libs, StaticList& addLibs, bool winrt); 298 | 299 | void buildDependencyValues(StaticList& includeDirs, StaticList& lib32Dirs, StaticList& lib64Dirs, 300 | StaticList& definesShared, StaticList& definesStatic, bool winrt) const; 301 | 302 | void buildProjectDependencies(map& projectDeps) const; 303 | 304 | void buildProjectGUIDs(map& keys) const; 305 | 306 | struct DCEParams 307 | { 308 | string define; 309 | string file; 310 | 311 | bool operator==(const string& compare) const 312 | { 313 | return (file == compare); 314 | } 315 | }; 316 | 317 | /** 318 | * Builds project specific DCE functions and variables that are not automatically detected. 319 | * @param [out] definitionsDCE The return list of built DCE functions. 320 | * @param [out] variablesDCE The return list of built DCE variables. 321 | */ 322 | void buildProjectDCEs(map& definitionsDCE, map& variablesDCE) const; 323 | 324 | bool checkProjectFiles(); 325 | 326 | /** 327 | * Builds '_wrap' files to wrap source files in a conditional compilation statement. 328 | * @param replaceIncludes The list of files to scan. 329 | * @param [in,out] existingIncludes The list of existing processed files. 330 | * @param [in,out] conditionalIncludes The list of existing conditional files. 331 | */ 332 | bool createReplaceFiles( 333 | const StaticList& replaceIncludes, StaticList& existingIncludes, ConditionalList& conditionalIncludes); 334 | 335 | bool findProjectFiles(const StaticList& includes, StaticList& includesC, StaticList& includesCPP, 336 | StaticList& includesASM, StaticList& includesH, StaticList& includesRC, StaticList& includesCU, 337 | StaticList& includesCL, StaticList& includesCOMP) const; 338 | 339 | /** 340 | * Replace occurrences of known tags in string. 341 | * @param [in,out] projectTemplate The project file in string form. 342 | * @param winrt Whether this is a winrt project file. 343 | */ 344 | void outputTemplateTags(string& projectTemplate, bool winrt = false) const; 345 | 346 | /** 347 | * Replace occurrences of features in a props file. 348 | * @param [in,out] projectTemplate The project file in string form. 349 | */ 350 | void outputPropsTags(string& projectTemplate) const; 351 | 352 | void outputSourceFileType(StaticList& fileList, const string& type, const string& filterType, 353 | string& projectTemplate, string& filterTemplate, StaticList& foundObjects, set& foundFilters, 354 | bool checkExisting, bool staticOnly = false, bool sharedOnly = false, bool bit32Only = false, 355 | bool bit64Only = false) const; 356 | 357 | void outputSourceFiles(string& projectTemplate, string& filterTemplate); 358 | 359 | /** 360 | * Find and load the list of function exports prefixes. 361 | * @param [out] exportPrefixes The list of loaded export prefixes. 362 | */ 363 | bool findExportsList(StaticList& exportPrefixes) const; 364 | 365 | /** 366 | * Generate a module definition file. 367 | * @param includeDirs The list of current directories to look for included files. 368 | */ 369 | bool outputProjectExports(const StaticList& includeDirs) const; 370 | 371 | /** 372 | * Executes a batch script to perform operations using a compiler based on current configuration. 373 | * @param includeDirs The list of current directories to look for included files. 374 | * @param [in,out] directoryObjects A list of subdirectories with each one containing a vector of files contained 375 | * within it. 376 | * @param runType The type of operation to run on input files (0=generate an sbr file, 1=pre- 377 | * process to .i file). 378 | * @returns True if it succeeds, false if it fails. 379 | */ 380 | bool runCompiler( 381 | const vector& includeDirs, map>& directoryObjects, int runType) const; 382 | 383 | /** 384 | * Executes a batch script to perform operations using the msvc compiler. 385 | * @param includeDirs The list of current directories to look for included files. 386 | * @param [in,out] directoryObjects A list of subdirectories with each one containing a vector of files contained 387 | * within it. 388 | * @param runType The type of operation to run on input files (0=generate an sbr file, 1=pre- 389 | * process to .i file). 390 | * @returns True if it succeeds, false if it fails. 391 | */ 392 | bool runMSVC(const vector& includeDirs, map>& directoryObjects, int runType) const; 393 | 394 | /** 395 | * Executes a bash script to perform operations using the gcc compiler. 396 | * @param includeDirs The list of current directories to look for included files. 397 | * @param [in,out] directoryObjects A list of subdirectories with each one containing a vector of files contained 398 | * within it. 399 | * @param runType The type of operation to run on input files (1=pre-process to .i file). 400 | * @returns True if it succeeds, false if it fails. 401 | */ 402 | bool runGCC(const vector& includeDirs, map>& directoryObjects, int runType) const; 403 | 404 | /** 405 | * Output additional build events to the project. 406 | * @param [in,out] projectTemplate The project template. 407 | */ 408 | void outputBuildEvents(string& projectTemplate) const; 409 | 410 | /** 411 | * Output additional include search directories to project. 412 | * @param includeDirs The include dirs. 413 | * @param [in,out] projectTemplate The project template. 414 | */ 415 | static void outputIncludeDirs(const StaticList& includeDirs, string& projectTemplate); 416 | 417 | /** 418 | * Output additional library search directories to project. 419 | * @param lib32Dirs The library 32b dirs. 420 | * @param lib64Dirs The library 64b dirs. 421 | * @param [in,out] projectTemplate The project template. 422 | */ 423 | static void outputLibDirs(const StaticList& lib32Dirs, const StaticList& lib64Dirs, string& projectTemplate); 424 | 425 | /** 426 | * Output additional defines to the project. 427 | * @param definesShared The defines for shared libraries. 428 | * @param definesStatic The defines for static libraires. 429 | * @param [in,out] projectTemplate The project template. 430 | * @param program (Optional) True if building program project. 431 | */ 432 | void outputDefines(const StaticList& definesShared, const StaticList& definesStatic, string& projectTemplate, 433 | bool program = false); 434 | 435 | /** 436 | * Output asm tools to project template. 437 | * @remark Either yasm or nasm tools will be used based on current configuration. 438 | * @param [in,out] projectTemplate The project template. 439 | */ 440 | void outputASMTools(string& projectTemplate) const; 441 | 442 | /** 443 | * Output cuda tools to project template. 444 | * @param [in,out] projectTemplate The project template. 445 | */ 446 | void outputCUDATools(string& projectTemplate) const; 447 | 448 | bool outputDependencyLibs(string& projectTemplate, bool winrt, bool program); 449 | 450 | /** 451 | * Search through files in the current project and finds any undefined elements that are used in DCE blocks. A new 452 | * file is then created and added to the project that contains hull definitions for any missing functions. 453 | * @param includeDirs The list of current directories to look for included files. 454 | * @return True if it succeeds, false if it fails. 455 | */ 456 | bool outputProjectDCE(const StaticList& includeDirs); 457 | 458 | /** 459 | * Passes an input file and looks for any function usage within a block of code eliminated by DCE. 460 | * @param file The loaded file to search for DCE usage in. 461 | * @param fileName Filename of the file currently being searched. 462 | * @param [in,out] foundDCEUsage The return list of found DCE functions. 463 | * @param [out] requiresPreProcess The file requires pre processing. 464 | * @param [in,out] nonDCEUsage The return list of found functions not in DCE. 465 | */ 466 | void outputProjectDCEFindFunctions(const string& file, const string& fileName, 467 | map& foundDCEUsage, bool& requiresPreProcess, set& nonDCEUsage) const; 468 | 469 | /** 470 | * Resolves a pre-processor define conditional string by replacing with current configuration settings. 471 | * @param [in,out] define The pre-processor define string. 472 | */ 473 | void outputProgramDCEsResolveDefine(string& define); 474 | 475 | /** 476 | * Find any declaration of a specified function. Can also find a definition of the function if no declaration as 477 | * found first. 478 | * @param file The loaded file to search for function in. 479 | * @param function The name of the function to search for. 480 | * @param fileName Filename of the file being searched through. 481 | * @param [out] retDeclaration Returns the complete declaration for the found function. 482 | * @param [out] isFunction Returns if the found declaration was actually for a function or an incorrectly 483 | * identified table/array declaration. 484 | * @return True if it succeeds finding the function, false if it fails. 485 | */ 486 | static bool outputProjectDCEsFindDeclarations( 487 | const string& file, const string& function, const string& fileName, string& retDeclaration, bool& isFunction); 488 | 489 | /** 490 | * Cleans a pre-processor define conditional string to remove any invalid values. 491 | * @param [in,out] define The pre-processor define string to clean. 492 | */ 493 | static void outputProjectDCECleanDefine(string& define); 494 | 495 | /** 496 | * Combines 2 pre-processor define conditional strings. 497 | * @param define The first define. 498 | * @param define2 The second define. 499 | * @param [out] retDefine The returned combined define. 500 | */ 501 | static void outputProgramDCEsCombineDefine(const string& define, const string& define2, string& retDefine); 502 | }; 503 | 504 | #endif 505 | -------------------------------------------------------------------------------- /project_generate.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | VisualStudioVersion = 12.0.30501.0 4 | MinimumVisualStudioVersion = 12.0.30501.0 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "project_generate", "project_generate.vcxproj", "{FA1D2C31-D809-4021-9DE4-7552704175EE}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x64 = Debug|x64 10 | Debug|x86 = Debug|x86 11 | Release|x64 = Release|x64 12 | Release|x86 = Release|x86 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Debug|x64.ActiveCfg = Debug|x64 16 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Debug|x64.Build.0 = Debug|x64 17 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Debug|x86.ActiveCfg = Debug|Win32 18 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Debug|x86.Build.0 = Debug|Win32 19 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Release|x64.ActiveCfg = Release|x64 20 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Release|x64.Build.0 = Release|x64 21 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Release|x86.ActiveCfg = Release|Win32 22 | {FA1D2C31-D809-4021-9DE4-7552704175EE}.Release|x86.Build.0 = Release|Win32 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /project_generate.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | {FA1D2C31-D809-4021-9DE4-7552704175EE} 43 | ffmpeg_generate 44 | project_generate 45 | 46 | 47 | 48 | Application 49 | true 50 | v143 51 | v142 52 | v141 53 | v140 54 | v120 55 | 56 | 57 | Application 58 | true 59 | v143 60 | v142 61 | v141 62 | v140 63 | v120 64 | 65 | 66 | Application 67 | false 68 | v143 69 | v142 70 | v141 71 | v140 72 | v120 73 | true 74 | 75 | 76 | Application 77 | false 78 | v143 79 | v142 80 | v141 81 | v140 82 | v120 83 | true 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | $(ProjectDir)\bin\ 103 | $(ProjectDir)\obj\$(Configuration)\$(Platform)\ 104 | $(ProjectName)d 105 | 106 | 107 | $(ProjectDir)\obj\$(Configuration)\$(Platform)\ 108 | $(ProjectName)d 109 | $(ProjectDir)\bin\ 110 | 111 | 112 | $(ProjectDir)\bin\ 113 | $(ProjectDir)\obj\$(Configuration)\$(Platform)\ 114 | 115 | 116 | $(ProjectDir)\obj\$(Configuration)\$(Platform)\ 117 | $(ProjectDir)\bin\ 118 | 119 | 120 | 121 | Level3 122 | Disabled 123 | _WIN32_WINNT=0x0501;_DEBUG;%(PreprocessorDefinitions) 124 | include;%(AdditionalIncludeDirectories) 125 | MultiThreadedDebug 126 | true 127 | 128 | 129 | true 130 | Shlwapi.lib;%(AdditionalDependencies) 131 | $(IntDir)$(TargetName).pdb 132 | Console 133 | 5.1 134 | 135 | 136 | 137 | 138 | Level3 139 | Disabled 140 | _WIN32_WINNT=0x0600;_DEBUG;%(PreprocessorDefinitions) 141 | include;%(AdditionalIncludeDirectories) 142 | MultiThreadedDebug 143 | true 144 | 145 | 146 | true 147 | Shlwapi.lib;%(AdditionalDependencies) 148 | $(IntDir)$(TargetName).pdb 149 | Console 150 | 6.0 151 | 152 | 153 | 154 | 155 | Level3 156 | true 157 | true 158 | include;%(AdditionalIncludeDirectories) 159 | AnySuitable 160 | Speed 161 | true 162 | true 163 | false 164 | MultiThreaded 165 | true 166 | _WIN32_WINNT=0x0501; 167 | 168 | 169 | true 170 | true 171 | true 172 | Shlwapi.lib;%(AdditionalDependencies) 173 | UseLinkTimeCodeGeneration 174 | $(IntDir)$(TargetName).pdb 175 | Console 176 | 5.1 177 | 178 | 179 | 180 | 181 | Level3 182 | true 183 | true 184 | include;%(AdditionalIncludeDirectories) 185 | AnySuitable 186 | Speed 187 | true 188 | true 189 | false 190 | MultiThreaded 191 | true 192 | _WIN32_WINNT=0x0600; 193 | 194 | 195 | true 196 | true 197 | true 198 | Shlwapi.lib;%(AdditionalDependencies) 199 | UseLinkTimeCodeGeneration 200 | $(IntDir)$(TargetName).pdb 201 | Console 202 | 6.0 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /project_generate.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | 61 | 62 | Resource Files 63 | 64 | 65 | -------------------------------------------------------------------------------- /source/Templates.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShiftMediaProject/FFVS-Project-Generator/a25ea00107e46d01df7279fbcd64876f7661305a/source/Templates.rc -------------------------------------------------------------------------------- /source/helperFunctions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2017 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "helperFunctions.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #ifdef _WIN32 29 | # include "Shlwapi.h" 30 | 31 | # include 32 | #else 33 | # include 34 | extern char _binary_template_sln_winrt_start[]; 35 | extern char _binary_template_sln_winrt_end[]; 36 | extern char _binary_template_vcxproj_start[]; 37 | extern char _binary_template_vcxproj_end[]; 38 | extern char _binary_template_vcxproj_filters_start[]; 39 | extern char _binary_template_vcxproj_filters_end[]; 40 | extern char _binary_template_program_vcxproj_start[]; 41 | extern char _binary_template_program_vcxproj_end[]; 42 | extern char _binary_template_program_vcxproj_filters_start[]; 43 | extern char _binary_template_program_vcxproj_filters_end[]; 44 | extern char _binary_template_bat_start[]; 45 | extern char _binary_template_bat_end[]; 46 | extern char _binary_template_vcxproj_winrt_start[]; 47 | extern char _binary_template_vcxproj_winrt_end[]; 48 | extern char _binary_template_props_start[]; 49 | extern char _binary_template_props_end[]; 50 | extern char _binary_template_props_winrt_start[]; 51 | extern char _binary_template_props_winrt_end[]; 52 | extern char _binary_template_file_props_start[]; 53 | extern char _binary_template_file_props_end[]; 54 | extern char _binary_template_sln_nowinrt_start[]; 55 | extern char _binary_template_sln_nowinrt_end[]; 56 | const char* pp_cStartArray[] = {_binary_template_sln_winrt_start, _binary_template_vcxproj_start, 57 | _binary_template_vcxproj_filters_start, _binary_template_program_vcxproj_start, 58 | _binary_template_program_vcxproj_filters_start, _binary_template_bat_start, _binary_template_vcxproj_winrt_start, 59 | _binary_template_props_start, _binary_template_props_winrt_start, _binary_template_file_props_start, 60 | _binary_template_sln_nowinrt_start}; 61 | const char* pp_cEndArray[] = {_binary_template_sln_winrt_end, _binary_template_vcxproj_end, 62 | _binary_template_vcxproj_filters_end, _binary_template_program_vcxproj_end, 63 | _binary_template_program_vcxproj_filters_end, _binary_template_bat_end, _binary_template_vcxproj_winrt_end, 64 | _binary_template_props_end, _binary_template_props_winrt_end, _binary_template_file_props_end, 65 | _binary_template_sln_nowinrt_end}; 66 | #endif 67 | 68 | #if _DEBUG 69 | static Verbosity s_outputVerbosity = VERBOSITY_INFO; 70 | #else 71 | static Verbosity s_outputVerbosity = VERBOSITY_WARNING; 72 | #endif 73 | 74 | namespace project_generate { 75 | bool loadFromFile(const string& fileName, string& retString, const bool binary, const bool outError) 76 | { 77 | // Open the input file 78 | ifstream inputFile(fileName, (binary) ? ios_base::in | ios_base::binary : ios_base::in); 79 | if (!inputFile.is_open()) { 80 | if (outError) { 81 | outputError("Failed opening file (" + fileName + ")"); 82 | } 83 | return false; 84 | } 85 | 86 | // Load whole file into internal string 87 | inputFile.seekg(0, std::ifstream::end); 88 | const uint bufferSize = static_cast(inputFile.tellg()); 89 | inputFile.seekg(0, std::ifstream::beg); 90 | retString.resize(bufferSize); 91 | inputFile.read(&retString[0], bufferSize); 92 | if (bufferSize != static_cast(inputFile.gcount())) { 93 | retString.resize(static_cast(inputFile.gcount())); 94 | } 95 | inputFile.close(); 96 | return true; 97 | } 98 | 99 | bool loadFromResourceFile(const int resourceID, string& retString) 100 | { 101 | #ifdef _WIN32 102 | // Can load directly from windows resource file 103 | const HINSTANCE hInst = GetModuleHandleA(nullptr); 104 | const HRSRC hRes = FindResourceA(hInst, MAKEINTRESOURCE(resourceID), RT_RCDATA); 105 | const HGLOBAL hMem = LoadResource(hInst, hRes); 106 | const DWORD size = SizeofResource(hInst, hRes); 107 | const char* resText = static_cast(LockResource(hMem)); 108 | 109 | // Copy across the file 110 | retString.reserve(size); 111 | retString.resize(size); 112 | memcpy(const_cast(retString.data()), resText, size); 113 | 114 | // Close Resource 115 | FreeResource(hMem); 116 | return true; 117 | #else 118 | // Requires text file to be converted into a binary using either: 119 | // ld -r -b binary -o resource.file.o resource.file (creates _binary_resource_file_start) 120 | // objcopy -B i386 -I binary -O elf32-i386 resource.file resource.file.o 121 | uint size = (uint)(&pp_cEndArray[resourceID - 100] - &pp_cStartArray[resourceID - 100]); 122 | retString.reserve(size); 123 | retString.resize(size); 124 | memcpy(const_cast(retString.data()), pp_cStartArray[resourceID - 100], size); 125 | return false; 126 | #endif 127 | } 128 | 129 | bool writeToFile(const string& fileName, const string& inString, const bool binary) 130 | { 131 | // Check for subdirectories 132 | const uint dirPos = fileName.rfind('/'); 133 | if (dirPos != string::npos) { 134 | const string cs = fileName.substr(0, dirPos); 135 | if (!makeDirectory(cs)) { 136 | outputError("Failed creating local " + cs + " directory"); 137 | return false; 138 | } 139 | } 140 | // Open output file 141 | ofstream ofOutputFile(fileName, (binary) ? ios_base::out | ios_base::binary : ios_base::out); 142 | if (!ofOutputFile.is_open()) { 143 | outputError("Failed opening output file (" + fileName + ")"); 144 | return false; 145 | } 146 | 147 | // Output inString to file and close 148 | ofOutputFile << inString; 149 | ofOutputFile.close(); 150 | return true; 151 | } 152 | 153 | bool copyResourceFile(const int resourceID, const string& destinationFile, const bool binary) 154 | { 155 | #ifdef _WIN32 156 | // Can load directly from windows resource file 157 | const HINSTANCE hInst = GetModuleHandleA(nullptr); 158 | const HRSRC hRes = FindResourceA(hInst, MAKEINTRESOURCE(resourceID), RT_RCDATA); 159 | const HGLOBAL hMem = LoadResource(hInst, hRes); 160 | DWORD size = SizeofResource(hInst, hRes); 161 | const char* resText = static_cast(LockResource(hMem)); 162 | 163 | // Copy across the file 164 | ofstream dest(destinationFile, (binary) ? ios_base::out | ios_base::binary : ios_base::out); 165 | if (!dest.is_open()) { 166 | FreeResource(hMem); 167 | return false; 168 | } 169 | if (!dest.write(resText, size)) { 170 | dest.close(); 171 | FreeResource(hMem); 172 | return false; 173 | } 174 | dest.close(); 175 | 176 | // Close Resource 177 | FreeResource(hMem); 178 | return true; 179 | #else 180 | uint size = (uint)(&pp_cEndArray[resourceID - 100] - &pp_cStartArray[resourceID - 100]); 181 | // Copy across the file 182 | ofstream dest(destinationFile, (binary) ? ios_base::out | ios_base::binary : ios_base::out); 183 | if (!dest.is_open()) { 184 | return false; 185 | } 186 | if (!dest.write(pp_cStartArray[resourceID - 100], size)) { 187 | dest.close(); 188 | return false; 189 | } 190 | dest.close(); 191 | return false; 192 | #endif 193 | } 194 | 195 | void deleteFile(const string& destinationFile) 196 | { 197 | #ifdef _WIN32 198 | DeleteFileA(destinationFile.c_str()); 199 | #else 200 | remove(destinationFile.c_str()); 201 | #endif 202 | } 203 | 204 | void deleteFolder(const string& destinationFolder) 205 | { 206 | #ifdef _WIN32 207 | const string delFolder = destinationFolder + '\0'; 208 | SHFILEOPSTRUCT file_op = {NULL, FO_DELETE, delFolder.c_str(), "", FOF_NO_UI, false, 0, ""}; 209 | SHFileOperationA(&file_op); 210 | #else 211 | DIR* p_Dir = opendir(destinationFolder.c_str()); 212 | size_t path_len = strlen(destinationFolder.c_str()); 213 | 214 | if (p_Dir) { 215 | struct dirent* p_Dirent; 216 | int iRet = 0; 217 | while (!iRet && (p_Dirent = readdir(p_Dir))) { 218 | /* Skip the names "." and ".." as we don't want to recurse on them. */ 219 | if (!strcmp(p_Dirent->d_name, ".") || !strcmp(p_Dirent->d_name, "..")) { 220 | continue; 221 | } 222 | size_t diPathLength = path_len + strlen(p_Dirent->d_name) + 2; 223 | char* p_cBuffer = malloc(diPathLength); 224 | 225 | int iRet2 = -1; 226 | if (p_cBuffer) { 227 | struct stat statbuf; 228 | snprintf(p_cBuffer, diPathLength, "%s/%s", destinationFolder.c_str(), p_Dirent->d_name); 229 | if (!stat(p_cBuffer, &statbuf)) { 230 | if (S_ISDIR(statbuf.st_mode)) { 231 | iRet2 = remove_directory(p_cBuffer); 232 | } else { 233 | iRet2 = unlink(p_cBuffer); 234 | } 235 | } 236 | free(p_cBuffer); 237 | } 238 | iRet = iRet2; 239 | } 240 | closedir(p_Dir); 241 | } 242 | rmdir(destinationFolder.c_str()); 243 | #endif 244 | } 245 | 246 | bool isFolderEmpty(const string& folder) 247 | { 248 | #ifdef _WIN32 249 | return PathIsDirectoryEmptyA(folder.c_str()) == TRUE; 250 | #else 251 | DIR* dir = opendir(folder.c_str()); 252 | if (dir == NULL) { 253 | // Not a directory or doesn't exist 254 | return false; 255 | } 256 | int n = 0; 257 | struct dirent* d; 258 | while ((d = readdir(dir)) != NULL) { 259 | if (++n > 2) { 260 | break; 261 | } 262 | } 263 | closedir(dir); 264 | return (n <= 2); 265 | #endif 266 | } 267 | 268 | bool copyFile(const string& sourceFolder, const string& destinationFolder) 269 | { 270 | #ifdef _WIN32 271 | return (CopyFileA(sourceFolder.c_str(), destinationFolder.c_str(), false) != 0); 272 | #else 273 | FILE* p_Source = fopen(sourceFolder.c_str(), "rb"); 274 | if (p_Source == NULL) 275 | return false; 276 | FILE* p_Dest = fopen(destinationFolder.c_str(), "wb"); 277 | if (p_Dest == NULL) { 278 | fclose(p_Source); 279 | return false; 280 | } 281 | size_t size; 282 | char p_cBuffer[BUFSIZ]; 283 | while (size = fread(p_cBuffer, sizeof(char), sizeof(p_cBuffer), p_Source)) { 284 | if (fwrite(p_cBuffer, sizeof(char), size, p_Dest) != size) { 285 | fclose(p_Source); 286 | fclose(p_Dest); 287 | return false; 288 | } 289 | } 290 | fclose(p_Source); 291 | fclose(p_Dest); 292 | #endif 293 | } 294 | 295 | string getCopywriteHeader(const string& decription) 296 | { 297 | return "/** " + decription + "\n\ 298 | *\n\ 299 | * Permission is hereby granted, free of charge, to any person obtaining a copy\n\ 300 | * of this software and associated documentation files (the \"Software\"), to deal\n\ 301 | * in the Software without restriction, including without limitation the rights\n\ 302 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\ 303 | * copies of the Software, and to permit persons to whom the Software is\n\ 304 | * furnished to do so, subject to the following conditions:\n\ 305 | *\n\ 306 | * The above copyright notice and this permission notice shall be included in\n\ 307 | * all copies or substantial portions of the Software.\n\ 308 | *\n\ 309 | * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\ 310 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\ 311 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n\ 312 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\ 313 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\ 314 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\ 315 | * THE SOFTWARE.\n\ 316 | */"; 317 | } 318 | 319 | bool makeDirectory(const string& directory) 320 | { 321 | #ifdef _WIN32 322 | const int ret = _mkdir(directory.c_str()); 323 | #else 324 | const int ret = mkdir(directory.c_str()); 325 | #endif 326 | if ((ret == 0) || (errno == EEXIST)) { 327 | return true; 328 | } 329 | if (errno == ENOENT) { 330 | // The parent directory doesnt exist 331 | uint pos = directory.find_last_of('/'); 332 | #if defined(_WIN32) 333 | if (pos == string::npos) { 334 | pos = directory.find_last_of('\\'); 335 | } 336 | #endif 337 | if (pos == string::npos) { 338 | return false; 339 | } 340 | if (!makeDirectory(directory.substr(0, pos))) { 341 | return false; 342 | } 343 | // Try again 344 | return makeDirectory(directory); 345 | } 346 | return false; 347 | } 348 | 349 | bool findFile(const string& fileName, string& retFileName) 350 | { 351 | #ifdef _WIN32 352 | WIN32_FIND_DATA searchFile; 353 | const HANDLE searchHandle = FindFirstFileA(fileName.c_str(), &searchFile); 354 | if (searchHandle != INVALID_HANDLE_VALUE) { 355 | // Update the return filename 356 | retFileName = searchFile.cFileName; 357 | FindClose(searchHandle); 358 | replace(retFileName.begin(), retFileName.end(), '\\', '/'); 359 | return true; 360 | } 361 | return false; 362 | #else 363 | glob_t glob_result; 364 | if (glob(fileName.c_str(), GLOB_TILDEE | GLOB_NOSORT | GLOB_NOESCAPE, NULL, &glob_result) == 0) { 365 | retFileName = string(glob_result.gl_pathv[0]); 366 | globfree(&glob_result); 367 | return true; 368 | } 369 | return false; 370 | #endif 371 | } 372 | 373 | bool findFiles(const string& fileSearch, vector& retFiles, const bool recursive) 374 | { 375 | #ifdef _WIN32 376 | WIN32_FIND_DATA searchFile; 377 | const uint startSize = retFiles.size(); 378 | string path; 379 | string searchTerm = fileSearch; 380 | uint pos = searchTerm.rfind('/'); 381 | if (pos != string::npos) { 382 | ++pos; 383 | path = fileSearch.substr(0, pos); 384 | searchTerm = fileSearch.substr(pos); 385 | } 386 | HANDLE searchHandle = FindFirstFile(fileSearch.c_str(), &searchFile); 387 | if (searchHandle != INVALID_HANDLE_VALUE) { 388 | // Update the return filename list 389 | retFiles.push_back(path + searchFile.cFileName); 390 | while (FindNextFile(searchHandle, &searchFile) != 0) { 391 | retFiles.push_back(path + searchFile.cFileName); 392 | replace(retFiles.back().begin(), retFiles.back().end(), '\\', '/'); 393 | } 394 | FindClose(searchHandle); 395 | } 396 | // Search all sub directories as well 397 | if (recursive) { 398 | const string search = path + "*"; 399 | searchHandle = FindFirstFile(search.c_str(), &searchFile); 400 | if (searchHandle != INVALID_HANDLE_VALUE) { 401 | BOOL cont = TRUE; 402 | while (cont == TRUE) { 403 | if (searchFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 404 | // this is a directory 405 | if (strcmp(searchFile.cFileName, ".") != 0 && strcmp(searchFile.cFileName, "..") != 0) { 406 | string newPath = path + searchFile.cFileName + '/' + searchTerm; 407 | findFiles(newPath, retFiles); 408 | } 409 | } 410 | cont = FindNextFile(searchHandle, &searchFile); 411 | } 412 | FindClose(searchHandle); 413 | } 414 | } 415 | return (retFiles.size() - startSize) > 0; 416 | #else 417 | glob_t glob_result; 418 | if (glob(sFileName.c_str(), GLOB_TILDEE | GLOB_NOSORT | GLOB_NOESCAPE, NULL, &glob_result) == 0) { 419 | for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) { 420 | retFiles.push_back(string(glob_result.gl_pathv[i])); 421 | } 422 | globfree(&glob_result); 423 | return (retFiles.size() - uiStartSize) > 0; 424 | } 425 | return false; 426 | #endif 427 | } 428 | 429 | bool findFolders(const string& folderSearch, vector& retFolders, const bool recursive) 430 | { 431 | #ifdef _WIN32 432 | WIN32_FIND_DATA searchFile; 433 | const uint startSize = retFolders.size(); 434 | string path; 435 | string searchTerm = folderSearch; 436 | uint pos = searchTerm.rfind('/'); 437 | if (pos == (searchTerm.length() - 1)) { 438 | pos = searchTerm.find_last_not_of('/'); 439 | pos = searchTerm.rfind('/', pos - 1); 440 | } 441 | if (pos != string::npos) { 442 | ++pos; 443 | path = folderSearch.substr(0, pos); 444 | searchTerm = folderSearch.substr(pos); 445 | } 446 | HANDLE searchHandle = FindFirstFileA(folderSearch.c_str(), &searchFile); 447 | if (searchHandle != INVALID_HANDLE_VALUE) { 448 | // Update the return filename list 449 | retFolders.push_back(path + searchFile.cFileName); 450 | while (FindNextFileA(searchHandle, &searchFile) != 0) { 451 | if (searchFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 452 | retFolders.push_back(path + searchFile.cFileName); 453 | replace(retFolders.back().begin(), retFolders.back().end(), '\\', '/'); 454 | } 455 | } 456 | FindClose(searchHandle); 457 | } 458 | // Search all sub directories as well 459 | if (recursive) { 460 | const string search = path + "*"; 461 | searchHandle = FindFirstFileA(search.c_str(), &searchFile); 462 | if (searchHandle != INVALID_HANDLE_VALUE) { 463 | BOOL cont = TRUE; 464 | while (cont == TRUE) { 465 | if (searchFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 466 | // this is a directory 467 | if (strcmp(searchFile.cFileName, ".") != 0 && strcmp(searchFile.cFileName, "..") != 0) { 468 | string newPath = path + searchFile.cFileName + '/' + searchTerm; 469 | findFolders(newPath, retFolders); 470 | } 471 | } 472 | cont = FindNextFileA(searchHandle, &searchFile); 473 | } 474 | FindClose(searchHandle); 475 | } 476 | } 477 | return (retFolders.size() - startSize) > 0; 478 | #else 479 | glob_t glob_result; 480 | if (glob(sFileName.c_str(), GLOB_TILDE | GLOB_NOSORT | GLOB_NOESCAPE | GLOB_ONLYDIR, NULL, &glob_result) == 0) { 481 | for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) { 482 | vRetFiles.push_back(string(glob_result.gl_pathv[i])); 483 | } 484 | globfree(&glob_result); 485 | return (vRetFiles.size() - uiStartSize) > 0; 486 | } 487 | return false; 488 | #endif 489 | } 490 | 491 | void makePathsRelative(const string& path, const string& makeRelativeTo, string& retPath) 492 | { 493 | #ifdef _WIN32 494 | retPath.reserve(MAX_PATH); 495 | retPath.resize(MAX_PATH); 496 | string fromT, toT; 497 | fromT.reserve(MAX_PATH); 498 | toT.reserve(MAX_PATH); 499 | if (path.length() > 0) { 500 | GetFullPathNameA(path.c_str(), MAX_PATH, const_cast(fromT.data()), NULL); 501 | } else { 502 | GetFullPathNameA("./", MAX_PATH, const_cast(fromT.data()), NULL); 503 | } 504 | if (makeRelativeTo.length() > 0) { 505 | GetFullPathNameA(makeRelativeTo.c_str(), MAX_PATH, const_cast(toT.data()), NULL); 506 | } else { 507 | GetFullPathNameA("./", MAX_PATH, const_cast(toT.data()), NULL); 508 | } 509 | PathRelativePathToA( 510 | const_cast(retPath.data()), toT.c_str(), FILE_ATTRIBUTE_DIRECTORY, fromT.c_str(), FILE_ATTRIBUTE_NORMAL); 511 | retPath.resize(strlen(retPath.c_str())); 512 | replace(retPath.begin(), retPath.end(), '\\', '/'); 513 | #else 514 | retPath.reserve(MAX_PATH); 515 | retPath.resize(MAX_PATH); 516 | string sFromT, sToT; 517 | sFromT.reserve(MAX_PATH); 518 | sToT.reserve(MAX_PATH); 519 | realpath(path.c_str(), const_cast(sFromT.data())); 520 | realpath(makeRelativeTo.c_str(), const_cast(sToT.data())); 521 | retPath.at(0) = '\0'; 522 | int iPos; 523 | int iSizeA = strlen(path.c_str()) + 1; 524 | int iSizeR = strlen(makeRelativeTo.c_str()) + 1; 525 | for (iPos = 0; iPos < iSizeA && iPos < iSizeR; iPos += strlen(path.c_str() + iPos) + 1) { 526 | const char* p_PosA = strchr(path.c_str() + iPos, '/'); 527 | const char* p_PosR = strchr(makeRelativeTo.c_str() + iPos, '/'); 528 | if (p_PosA) 529 | const_cast(p_PosA)[0] = '\0'; 530 | if (p_PosR) 531 | const_cast(p_PosR)[0] = '\0'; 532 | if (strcmp(path.c_str() + iPos, makeRelativeTo.c_str() + iPos) != 0) 533 | break; 534 | } 535 | for (int iPos2 = iPos; iPos2 < iSizeR; iPos2 += strlen(makeRelativeTo.c_str() + iPos2) + 1) { 536 | strcat(const_cast(retPath.data()), "../"); 537 | if (!strchr(retPath.c_str() + iPos2, '/')) 538 | break; 539 | } 540 | if (iPos < iSizeA) 541 | strcat(const_cast(retPath.data()), path.c_str() + iPos); 542 | retPath.resize(strlen(retPath.c_str())); 543 | #endif 544 | } 545 | 546 | void removeWhiteSpace(string& inputString) 547 | { 548 | struct RemoveDelimiter 549 | { 550 | bool operator()(const char c) const 551 | { 552 | return (g_whiteSpace.find(c) != string::npos); 553 | } 554 | }; 555 | 556 | inputString.erase(remove_if(inputString.begin(), inputString.end(), RemoveDelimiter()), inputString.end()); 557 | } 558 | 559 | void findAndReplace(string& inString, const string& search, const string& replace) 560 | { 561 | uint uiPos = 0; 562 | while ((uiPos = inString.find(search, uiPos)) != std::string::npos) { 563 | inString.replace(uiPos, search.length(), replace); 564 | uiPos += replace.length(); 565 | } 566 | } 567 | 568 | bool findEnvironmentVariable(const string& envVar) 569 | { 570 | #ifdef _WIN32 571 | return (GetEnvironmentVariableA(envVar.c_str(), NULL, 0) > 0); 572 | #else 573 | return false; 574 | #endif 575 | } 576 | 577 | void pressKeyToContinue() 578 | { 579 | #if _WIN32 580 | system("pause"); 581 | #else 582 | system("read -rsn 1 -p \"Press any key to continue...\""); 583 | #endif 584 | } 585 | 586 | void outputLine(const string& message) 587 | { 588 | cout << message << endl; 589 | } 590 | 591 | void outputInfo(const string& message, const bool header) 592 | { 593 | #if _WIN32 594 | const HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); 595 | CONSOLE_SCREEN_BUFFER_INFO csbi; 596 | GetConsoleScreenBufferInfo(hstdout, &csbi); 597 | SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); 598 | #endif 599 | if (s_outputVerbosity <= VERBOSITY_INFO) { 600 | if (header) { 601 | cout << " Info: "; 602 | } else { 603 | cout << " "; 604 | } 605 | cout << message << endl; 606 | } 607 | #if _WIN32 608 | SetConsoleTextAttribute(hstdout, csbi.wAttributes); 609 | #endif 610 | } 611 | 612 | void outputWarning(const string& message, const bool header) 613 | { 614 | #if _WIN32 615 | const HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); 616 | CONSOLE_SCREEN_BUFFER_INFO csbi; 617 | GetConsoleScreenBufferInfo(hstdout, &csbi); 618 | SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_GREEN); 619 | #endif 620 | if (s_outputVerbosity <= VERBOSITY_WARNING) { 621 | if (header) { 622 | cout << " Warning: "; 623 | } else { 624 | cout << " "; 625 | } 626 | cout << message << endl; 627 | } 628 | #if _WIN32 629 | SetConsoleTextAttribute(hstdout, csbi.wAttributes); 630 | #endif 631 | } 632 | 633 | void outputError(const string& message, const bool header) 634 | { 635 | #if _WIN32 636 | const HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); 637 | CONSOLE_SCREEN_BUFFER_INFO csbi; 638 | GetConsoleScreenBufferInfo(hstdout, &csbi); 639 | SetConsoleTextAttribute(hstdout, FOREGROUND_RED); 640 | #endif 641 | if (header) { 642 | cout << " Error: "; 643 | } else { 644 | cout << " "; 645 | } 646 | cout << message << endl; 647 | #if _WIN32 648 | SetConsoleTextAttribute(hstdout, csbi.wAttributes); 649 | #endif 650 | } 651 | 652 | void setOutputVerbosity(const Verbosity verbose) 653 | { 654 | s_outputVerbosity = verbose; 655 | } 656 | }; // namespace project_generate 657 | -------------------------------------------------------------------------------- /source/projectGenerator_compiler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2017 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "projectGenerator.h" 22 | 23 | #include 24 | #include 25 | 26 | bool ProjectGenerator::runCompiler( 27 | const vector& includeDirs, map>& directoryObjects, const int runType) const 28 | { 29 | #ifdef _MSC_VER 30 | // If compiled by msvc then only msvc builds are supported 31 | return runMSVC(includeDirs, directoryObjects, runType); 32 | #else 33 | // Otherwise only gcc and mingw are supported 34 | return runGCC(includeDirs, directoryObjects, runType); 35 | #endif 36 | } 37 | 38 | bool ProjectGenerator::runMSVC( 39 | const vector& includeDirs, map>& directoryObjects, int runType) const 40 | { 41 | // Create a test file to read in definitions 42 | string outDir = m_configHelper.m_outDirectory; 43 | m_configHelper.makeFileGeneratorRelative(outDir, outDir); 44 | string projectDir = m_configHelper.m_solutionDirectory; 45 | m_configHelper.makeFileGeneratorRelative(projectDir, projectDir); 46 | vector includeDirs2 = includeDirs; 47 | includeDirs2.insert(includeDirs2.begin(), outDir + "include/"); 48 | includeDirs2.insert(includeDirs2.begin(), m_configHelper.m_solutionDirectory); 49 | includeDirs2.insert(includeDirs2.begin(), m_configHelper.m_rootDirectory); 50 | string extraCl; 51 | for (auto& i : includeDirs2) { 52 | uint findPos2 = i.find("$(OutDir)"); 53 | if (findPos2 != string::npos) { 54 | i.replace(findPos2, 9, outDir); 55 | } 56 | findPos2 = i.find("$(OutBaseDir)"); 57 | if (findPos2 != string::npos) { 58 | i.replace(findPos2, 13, outDir); 59 | } 60 | findPos2 = i.find("$(ProjectDir)"); 61 | if (findPos2 != string::npos) { 62 | i.replace(findPos2, 13, projectDir); 63 | } 64 | findPos2 = i.find("$("); 65 | if (findPos2 != string::npos) { 66 | i.replace(findPos2, 2, "%"); 67 | } 68 | findPos2 = i.find(')'); 69 | if (findPos2 != string::npos) { 70 | i.replace(findPos2, 1, "%"); 71 | } 72 | if (i.length() == 0) { 73 | i = "./"; 74 | } else if ((i.find(':') == string::npos) && (i.find_first_of("./%") != 0)) { 75 | i.insert(0, "./"); 76 | } 77 | // Clean duplicate '//' 78 | findPos2 = i.find("//"); 79 | while (findPos2 != string::npos) { 80 | i.erase(findPos2, 1); 81 | // get next 82 | findPos2 = i.find("//"); 83 | } 84 | // Remove ../ not at start of path 85 | findPos2 = i.find("/../"); 86 | while (findPos2 != string::npos) { 87 | // Get the previous '/' 88 | uint findPos3 = i.rfind('/', findPos2 - 1); 89 | findPos3 = (findPos3 != string::npos) ? findPos3 : 0; 90 | if (i.find_first_not_of('.', findPos3 + 1) < findPos2) { 91 | i.erase(findPos3, findPos2 - findPos3 + 3); 92 | // get next 93 | findPos2 = i.find("/../", findPos3); 94 | } else { 95 | // get next 96 | findPos2 = i.find("/../", findPos2 + 1); 97 | } 98 | } 99 | extraCl += " /I\"" + i + '\"'; 100 | } 101 | string tempFolder = m_tempDirectory + m_projectName; 102 | 103 | // Use Microsoft compiler to pass the test file and retrieve declarations 104 | string launchBat = "@echo off\nsetlocal enabledelayedexpansion\nset CALLDIR=%CD%\n"; 105 | launchBat += "if \"%PROCESSOR_ARCHITECTURE%\"==\"AMD64\" (\n\ 106 | set SYSARCH=64\n\ 107 | ) else if \"%PROCESSOR_ARCHITECTURE%\"==\"x86\" (\n\ 108 | if \"%PROCESSOR_ARCHITEW6432%\"==\"AMD64\" (\n\ 109 | set SYSARCH=64\n\ 110 | ) else (\n\ 111 | set SYSARCH=32\n\ 112 | )\n\ 113 | ) else (\n\ 114 | echo fatal error : Current Platform Architecture could not be detected. > ffvs_log.txt\n\ 115 | exit /b 1\n\ 116 | )\n\ 117 | if \"%SYSARCH%\"==\"32\" (\n\ 118 | set MSVCVARSDIR=\n\ 119 | set VSWHERE=\"%ProgramFiles%\\Microsoft Visual Studio\\Installer\\vswhere.exe\"\n\ 120 | ) else if \"%SYSARCH%\"==\"64\" (\n\ 121 | set MSVCVARSDIR=\\amd64\n\ 122 | set VSWHERE=\"%ProgramFiles(x86)%\\Microsoft Visual Studio\\Installer\\vswhere.exe\"\n\ 123 | )\n\ 124 | if exist %VSWHERE% (\n\ 125 | for /f \"usebackq delims=\" %%i in (`%VSWHERE% -prerelease -latest -property installationPath`) do (set VSINSTDIR=%%i)\n\ 126 | if exist \"!VSINSTDIR!\\VC\\Auxiliary\\Build\\vcvars%SYSARCH%.bat\" (\n\ 127 | call \"!VSINSTDIR!\\VC\\Auxiliary\\Build\\vcvars%SYSARCH%.bat\" >nul 2>&1\n\ 128 | goto MSVCVarsDone\n\ 129 | )\n\ 130 | if exist \"!VSINSTDIR!\\..\\..\\VC\\bin%MSVCVARSDIR%\\vcvars%SYSARCH%.bat\" (\n\ 131 | call \"!VSINSTDIR!\\..\\..\\VC\\bin%MSVCVARSDIR%\\vcvars%SYSARCH%.bat\" >nul 2>&1\n\ 132 | goto MSVCVarsDone\n\ 133 | )\n\ 134 | )\n\ 135 | if \"%SYSARCH%\"==\"32\" (\n\ 136 | set WOWNODE=\n\ 137 | ) else if \"%SYSARCH%\"==\"64\" (\n\ 138 | set WOWNODE=\\WOW6432Node\n\ 139 | )\n\ 140 | pushd %CD%\n\ 141 | reg.exe query \"HKLM\\SOFTWARE%WOWNODE%\\Microsoft\\VisualStudio\\SxS\\VS7\" /v 15.0 >nul 2>&1\n\ 142 | if not ERRORLEVEL 1 (\n\ 143 | for /f \"skip=2 tokens=2,*\" %%a in ('reg.exe query \"HKLM\\SOFTWARE%WOWNODE%\\Microsoft\\VisualStudio\\SxS\\VS7\" /v 15.0') do (set VSINSTDIR=%%b)\n\ 144 | call \"!VSINSTDIR!VC\\Auxiliary\\Build\\vcvars%SYSARCH%.bat\" >nul 2>&1\n\ 145 | goto MSVCVarsDone\n\ 146 | )\n\ 147 | reg.exe query \"HKLM\\Software%WOWNODE%\\Microsoft\\VisualStudio\\14.0\" /v \"InstallDir\" >nul 2>&1\n\ 148 | if not ERRORLEVEL 1 (\n\ 149 | for /f \"skip=2 tokens=2,*\" %%a in ('reg.exe query \"HKLM\\Software%WOWNODE%\\Microsoft\\VisualStudio\\14.0\" /v \"InstallDir\"') do (set VSINSTDIR=%%b)\n\ 150 | call \"!VSINSTDIR!\\..\\..\\VC\\bin%MSVCVARSDIR%\\vcvars%SYSARCH%.bat\" >nul 2>&1\n\ 151 | goto MSVCVarsDone\n\ 152 | )\n\ 153 | reg.exe query \"HKLM\\Software%WOWNODE%\\Microsoft\\VisualStudio\\12.0\" /v \"InstallDir\" >nul 2>&1\n\ 154 | if not ERRORLEVEL 1 (\n\ 155 | for /f \"skip=2 tokens=2,*\" %%a in ('reg.exe query \"HKLM\\Software%WOWNODE%\\Microsoft\\VisualStudio\\12.0\" /v \"InstallDir\"') do (set VSINSTDIR=%%b)\n\ 156 | call \"!VSINSTDIR!\\..\\..\\VC\\bin%MSVCVARSDIR%\\vcvars%SYSARCH%.bat\" >nul 2>&1\n\ 157 | goto MSVCVarsDone\n\ 158 | )\n\ 159 | echo fatal error : An installed version of Visual Studio could not be detected. > ffvs_log.txt\n\ 160 | exit /b 1\n\ 161 | :MSVCVarsDone\n\ 162 | popd\n"; 163 | launchBat += "mkdir \"" + m_tempDirectory + "\" > nul 2>&1\n"; 164 | launchBat += "mkdir \"" + tempFolder + "\" > nul 2>&1\n"; 165 | for (auto& j : directoryObjects) { 166 | const uint rowSize = 32; 167 | uint numClCalls = static_cast(ceilf(static_cast(j.second.size()) / static_cast(rowSize))); 168 | uint totalPos = 0; 169 | string dirName = tempFolder + "/" + j.first; 170 | if (j.first.length() > 0) { 171 | // Need to make output directory so compile doesn't fail outputting 172 | launchBat += "mkdir \"" + dirName + "\" > nul 2>&1\n"; 173 | } 174 | string runCommands; 175 | // Check type of compiler call 176 | if (runType == 0) { 177 | runCommands = "/FR\"" + dirName + "/\"" + " /Fo\"" + dirName + "/\""; 178 | } else if (runType == 1) { 179 | runCommands = "/EP /P"; 180 | } 181 | 182 | // Split calls into groups of `rowSize` to prevent batch file length limit 183 | for (uint i = 0; i < numClCalls; i++) { 184 | uint uiStartPos = totalPos; 185 | // Create list of files for this batch 186 | vector compileFiles; 187 | vector extraIncludeDirs; 188 | compileFiles.reserve(rowSize); 189 | string extraExtraCl; 190 | for (; totalPos < min(uiStartPos + rowSize, j.second.size()); totalPos++) { 191 | if (runType == 0) { 192 | m_configHelper.makeFileGeneratorRelative(j.second[totalPos], j.second[totalPos]); 193 | } 194 | compileFiles.push_back(j.second[totalPos]); 195 | // Add any additional include dirs based on file paths (this is required for 'wrap' files) 196 | const auto dirPos = j.second[totalPos].rfind('/'); 197 | if (dirPos != string::npos) { 198 | string directory = j.second[totalPos].substr(0, dirPos + 1); 199 | if (directory.find(".") != 0) { 200 | directory = "./" + directory; 201 | } 202 | if (directory != m_configHelper.m_rootDirectory + m_projectName + '/' && 203 | find(includeDirs2.begin(), includeDirs2.end(), directory) == includeDirs2.end() && 204 | find(extraIncludeDirs.begin(), extraIncludeDirs.end(), directory) == extraIncludeDirs.end()) { 205 | extraIncludeDirs.push_back(directory); 206 | extraExtraCl += " /I\"" + directory + '\"'; 207 | } 208 | } 209 | } 210 | launchBat += "cl.exe "; 211 | launchBat += extraCl + extraExtraCl + 212 | R"( /D"_DEBUG" /D"WIN32" /D"_WINDOWS" /D"HAVE_AV_CONFIG_H" /D"_USE_MATH_DEFINES" /D"_UCRT_NOISY_NAN" )" + runCommands + 213 | " /c /MP /w /nologo /utf-8"; 214 | for (const auto& file : compileFiles) { 215 | launchBat += " \"" + file + "\""; 216 | } 217 | launchBat += " > ffvs_log.txt 2>&1\nif %errorlevel% neq 0 goto exitFail\n"; 218 | } 219 | if (runType == 1) { 220 | launchBat += "move *.i " + dirName + "/ >nul 2>&1\n"; 221 | } 222 | } 223 | if (runType == 0) { 224 | launchBat += "del /F /S /Q *.obj >nul 2>&1\n"; 225 | } 226 | launchBat += "del ffvs_log.txt >nul 2>&1\n"; 227 | launchBat += "exit /b 0\n:exitFail\n"; 228 | if (runType == 1) { 229 | launchBat += "del /F /S /Q *.i >nul 2>&1\n"; 230 | } 231 | launchBat += "rmdir /S /Q " + m_tempDirectory + "\nexit /b 1"; 232 | if (!writeToFile("ffvs_compile.bat", launchBat)) { 233 | return false; 234 | } 235 | 236 | if (0 != system("ffvs_compile.bat")) { 237 | outputError("Errors detected during compilation :-"); 238 | string testOutput; 239 | if (loadFromFile("ffvs_log.txt", testOutput)) { 240 | // Output errors from ffvs_log.txt 241 | bool error = false; 242 | bool missingVs = false; 243 | bool missingDeps = false; 244 | uint findPos = testOutput.find(" error "); 245 | while (findPos != string::npos) { 246 | // find end of line 247 | uint findPos2 = testOutput.find_first_of("\n(", findPos + 1); 248 | string temp = testOutput.substr(findPos + 1, findPos2 - findPos - 1); 249 | outputError(temp, false); 250 | findPos = testOutput.find(" error ", findPos2 + 1); 251 | // Check what type of error was found 252 | if (!missingDeps && (temp.find("open include file") != string::npos)) { 253 | missingDeps = true; 254 | } else if (!missingVs && (temp.find("Visual Studio could not be detected") != string::npos)) { 255 | missingVs = true; 256 | } else { 257 | error = true; 258 | } 259 | } 260 | findPos = testOutput.find("internal or external command"); 261 | if (findPos != string::npos) { 262 | uint findPos2 = testOutput.find('\n', findPos + 1); 263 | findPos = testOutput.rfind('\n', findPos); 264 | findPos = (findPos == string::npos) ? 0 : findPos; 265 | outputError(testOutput.substr(findPos, findPos2 - findPos), false); 266 | missingVs = true; 267 | } 268 | if (missingVs) { 269 | outputError( 270 | "Based on the above error(s) Visual Studio is not installed correctly on the host system.", false); 271 | outputError("Install a compatible version of Visual Studio before trying again.", false); 272 | deleteFile("ffvs_log.txt"); 273 | } else if (missingDeps) { 274 | outputError( 275 | "Based on the above error(s) there are files required for dependency libraries that are not available", 276 | false); 277 | outputError( 278 | "Ensure that any required dependencies are available in 'OutDir' based on the supplied configuration options before trying again.", 279 | false); 280 | outputError("Consult the supplied readme for instructions for installing varying dependencies.", false); 281 | outputError( 282 | "If a dependency has been cloned from a ShiftMediaProject repository then ensure it has been successfully built before trying again.", 283 | false); 284 | outputError( 285 | " Removing the offending configuration option can also be used to remove the error.", false); 286 | deleteFile("ffvs_log.txt"); 287 | } else if (error) { 288 | outputError("Unknown error detected. See ffvs_log.txt for further details.", false); 289 | } 290 | } 291 | // Remove the compile files 292 | deleteFile("ffvs_compile.bat"); 293 | deleteFolder(m_tempDirectory); 294 | return false; 295 | } 296 | 297 | // Remove the compilation objects 298 | deleteFile("ffvs_compile.bat"); 299 | return true; 300 | } 301 | 302 | bool ProjectGenerator::runGCC( 303 | const vector& includeDirs, map>& directoryObjects, int runType) const 304 | { 305 | // Create a test file to read in definitions 306 | string outDir = m_configHelper.m_outDirectory; 307 | m_configHelper.makeFileGeneratorRelative(outDir, outDir); 308 | string projectDir = m_configHelper.m_solutionDirectory; 309 | m_configHelper.makeFileGeneratorRelative(projectDir, projectDir); 310 | vector includeDirs2 = includeDirs; 311 | includeDirs2.insert(includeDirs2.begin(), outDir + "include/"); 312 | includeDirs2.insert(includeDirs2.begin(), m_configHelper.m_solutionDirectory); 313 | includeDirs2.insert(includeDirs2.begin(), m_configHelper.m_rootDirectory); 314 | string extraCl; 315 | for (auto& i : includeDirs2) { 316 | uint findPos2 = i.find("$(OutDir)"); 317 | if (findPos2 != string::npos) { 318 | i.replace(findPos2, 9, outDir); 319 | } 320 | findPos2 = i.find("$(OutBaseDir)"); 321 | if (findPos2 != string::npos) { 322 | i.replace(findPos2, 13, outDir); 323 | } 324 | findPos2 = i.find("$(ProjectDir)"); 325 | if (findPos2 != string::npos) { 326 | i.replace(findPos2, 13, projectDir); 327 | } 328 | findPos2 = i.find("$("); 329 | if (findPos2 != string::npos) { 330 | i.replace(findPos2, 2, "%"); 331 | } 332 | findPos2 = i.find(')'); 333 | if (findPos2 != string::npos) { 334 | i.replace(findPos2, 1, "%"); 335 | } 336 | if (i.length() == 0) { 337 | i = "./"; 338 | } else if ((i.find(':') == string::npos) && (i.find_first_of("./%") != 0)) { 339 | i.insert(0, "./"); 340 | } 341 | // Clean duplicate '//' 342 | findPos2 = i.find("//"); 343 | while (findPos2 != string::npos) { 344 | i.erase(findPos2, 1); 345 | // get next 346 | findPos2 = i.find("//"); 347 | } 348 | // Remove ../ not at start of path 349 | findPos2 = i.find("/../"); 350 | while (findPos2 != string::npos) { 351 | // Get the previous '/' 352 | uint findPos3 = i.rfind('/', findPos2 - 1); 353 | findPos3 = (findPos3 != string::npos) ? findPos3 : 0; 354 | if (i.find_first_not_of('.', findPos3 + 1) < findPos2) { 355 | i.erase(findPos3, findPos2 - findPos3 + 3); 356 | // get next 357 | findPos2 = i.find("/../", findPos3); 358 | } else { 359 | // get next 360 | findPos2 = i.find("/../", findPos2 + 1); 361 | } 362 | } 363 | extraCl += " /I\"" + i + '\"'; 364 | } 365 | string tempFolder = m_tempDirectory + m_projectName; 366 | 367 | // Use GNU compiler to pass the test file and retrieve declarations 368 | string launchBat = "#!/bin/bash\n"; 369 | launchBat += "exitFail() {\n"; 370 | if (runType == 1) { 371 | launchBat += "rm -rf *.i > /dev/null 2>&1\n"; 372 | } 373 | launchBat += "rm -rf " + m_tempDirectory + " > /dev/null 2>&1\nexit 1\n}\n"; 374 | launchBat += "mkdir \"" + m_tempDirectory + "\" > /dev/null 2>&1\n"; 375 | launchBat += "mkdir \"" + tempFolder + "\" > /dev/null 2>&1\n"; 376 | for (auto& i : directoryObjects) { 377 | string dirName = tempFolder + "/" + i.first; 378 | if (i.first.length() > 0) { 379 | // Need to make output directory so compile doesn't fail outputting 380 | launchBat += "mkdir \"" + dirName + "\" > /dev/null 2>&1\n"; 381 | } 382 | string runCommands; 383 | // Check type of compiler call 384 | if (runType == 0) { 385 | outputError("Generation of definitions is not supported using gcc."); 386 | return false; 387 | } 388 | if (runType == 1) { 389 | runCommands = "-E -P"; 390 | } 391 | // Check if gcc or mingw 392 | #ifdef _WIN32 393 | extraCl += R"(-D"WIN32" -D"_WINDOWS")"; 394 | #endif 395 | 396 | // Split calls as gcc outputs a single file at a time 397 | for (auto& j : i.second) { 398 | launchBat += "gcc "; 399 | launchBat += extraCl + " -D_DEBUG " + runCommands + " -c -w"; 400 | if (runType == 0) { 401 | m_configHelper.makeFileGeneratorRelative(j, j); 402 | } 403 | launchBat += " \"" + j + "\""; 404 | if (runType == 0) { 405 | launchBat += " -o " + j + ".o"; 406 | } else if (runType == 1) { 407 | launchBat += " -o " + j + ".i"; 408 | } 409 | launchBat += " > ffvs_log.txt 2>&1\nif (( $? )); then\nexitFail\nfi\n"; 410 | } 411 | } 412 | if (runType == 0) { 413 | launchBat += "rm -rf *.o > /dev/null 2>&1\n"; 414 | } 415 | launchBat += "rm ffvs_log.txt > /dev/null 2>&1\n"; 416 | launchBat += "exit 0\n"; 417 | if (!writeToFile("ffvs_compile.sh", launchBat)) { 418 | return false; 419 | } 420 | if (0 != system("ffvs_compile.sh")) { 421 | outputError("Errors detected during compilation :-"); 422 | outputError("Unknown error detected. See ffvs_log.txt for further details.", false); 423 | // Remove the compilation files 424 | deleteFile("ffvs_compile.sh"); 425 | deleteFolder(m_tempDirectory); 426 | return false; 427 | } 428 | 429 | // Remove the compilation objects 430 | deleteFile("ffvs_compile.sh"); 431 | return true; 432 | } 433 | -------------------------------------------------------------------------------- /source/projectGenerator_files.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2017 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "projectGenerator.h" 22 | 23 | #include 24 | #include 25 | 26 | bool ProjectGenerator::findSourceFile(const string& file, const string& extension, string& retFileName) const 27 | { 28 | string fileName; 29 | retFileName = m_projectDir + file + extension; 30 | if (!findFile(retFileName, fileName)) { 31 | // Check if this is a built file 32 | uint pos = m_projectDir.rfind('/', m_projectDir.length() - 2); 33 | pos = (pos == string::npos) ? 0 : pos + 1; 34 | string projectName = m_projectDir.substr(pos); 35 | projectName = (m_projectDir != "./") ? projectName : ""; 36 | retFileName = m_configHelper.m_solutionDirectory + projectName + file + extension; 37 | if (!findFile(retFileName, fileName)) { 38 | // Check if this file already includes the project folder in its name 39 | if (file.find(projectName) != string::npos) { 40 | retFileName = m_projectDir + file.substr(file.find(projectName) + projectName.length()) + extension; 41 | return findFile(retFileName, fileName); 42 | } 43 | return false; 44 | } 45 | } 46 | return true; 47 | } 48 | 49 | bool ProjectGenerator::findSourceFiles(const string& file, const string& extension, vector& retFiles) const 50 | { 51 | const string fileName = m_projectDir + file + extension; 52 | return findFiles(fileName, retFiles); 53 | } 54 | 55 | bool ProjectGenerator::checkProjectFiles() 56 | { 57 | // Check that all headers are correct 58 | for (auto& include : m_includesH) { 59 | string retFileName; 60 | if (!findSourceFile(include, ".h", retFileName)) { 61 | outputError("Could not find input header file for object (" + include + ")"); 62 | return false; 63 | } 64 | // Update the entry with the found file with complete path 65 | m_configHelper.makeFileProjectRelative(retFileName, include); 66 | } 67 | 68 | // Check that all C Source are correct 69 | for (auto& include : m_includesC) { 70 | string retFileName; 71 | if (!findSourceFile(include, ".c", retFileName)) { 72 | outputError("Could not find input C source file for object (" + include + ")"); 73 | return false; 74 | } 75 | // Update the entry with the found file with complete path 76 | m_configHelper.makeFileProjectRelative(retFileName, include); 77 | } 78 | 79 | // Check that all CPP Source are correct 80 | for (auto& include : m_includesCPP) { 81 | string retFileName; 82 | if (!findSourceFile(include, ".cpp", retFileName)) { 83 | outputError("Could not find input C++ source file for object (" + include + ")"); 84 | return false; 85 | } 86 | // Update the entry with the found file with complete path 87 | m_configHelper.makeFileProjectRelative(retFileName, include); 88 | } 89 | 90 | // Check that all ASM Source are correct 91 | for (auto& include : m_includesASM) { 92 | string retFileName; 93 | if (!findSourceFile(include, ".asm", retFileName)) { 94 | outputError("Could not find input ASM source file for object (" + include + ")"); 95 | return false; 96 | } 97 | // Update the entry with the found file with complete path 98 | m_configHelper.makeFileProjectRelative(retFileName, include); 99 | } 100 | 101 | // Check the output Unknown Includes and find there corresponding file 102 | if (!findProjectFiles(m_includes, m_includesC, m_includesCPP, m_includesASM, m_includesH, m_includesRC, 103 | m_includesCU, m_includesCL, m_includesCOMP)) { 104 | return false; 105 | } 106 | 107 | if (m_configHelper.m_onlyDCE) { 108 | // Don't need to check for replace files 109 | return true; 110 | } 111 | 112 | // Check all source files associated with replaced config values 113 | StaticList replaceIncludes, replaceCPPIncludes, replaceCIncludes, replaceASMIncludes, replaceCUIncludes, 114 | replaceCLIncludes, replaceCOMPIncludes; 115 | for (auto& include : m_replaceIncludes) { 116 | replaceIncludes.push_back(include.first); 117 | } 118 | if (!findProjectFiles(replaceIncludes, replaceCIncludes, replaceCPPIncludes, replaceASMIncludes, m_includesH, 119 | m_includesRC, replaceCUIncludes, replaceCLIncludes, replaceCOMPIncludes)) { 120 | return false; 121 | } 122 | // Need to create local files for any replace objects 123 | if (!createReplaceFiles(replaceCIncludes, m_includesC, m_includesConditionalC)) { 124 | return false; 125 | } 126 | if (!createReplaceFiles(replaceCPPIncludes, m_includesCPP, m_includesConditionalCPP)) { 127 | return false; 128 | } 129 | if (!createReplaceFiles(replaceASMIncludes, m_includesASM, m_includesConditionalASM)) { 130 | return false; 131 | } 132 | if (!createReplaceFiles(replaceCUIncludes, m_includesCU, m_includesConditionalCU)) { 133 | return false; 134 | } 135 | if (!createReplaceFiles(replaceCLIncludes, m_includesCL, m_includesConditionalCL)) { 136 | return false; 137 | } 138 | if (!createReplaceFiles(replaceCOMPIncludes, m_includesCOMP, m_includesConditionalCOMP)) { 139 | return false; 140 | } 141 | return true; 142 | } 143 | 144 | bool ProjectGenerator::createReplaceFiles( 145 | const StaticList& replaceIncludes, StaticList& existingIncludes, ConditionalList& conditionalIncludes) 146 | { 147 | for (const auto& replaceInclude : replaceIncludes) { 148 | // Check hasn't already been included as a fixed object 149 | if (find(existingIncludes.begin(), existingIncludes.end(), replaceInclude) != existingIncludes.end()) { 150 | // skip this item 151 | continue; 152 | } 153 | // Convert file to format required to search ReplaceIncludes 154 | const uint extPos = replaceInclude.rfind('.'); 155 | const uint cutPos = replaceInclude.rfind('/') + 1; 156 | string filename = replaceInclude.substr(cutPos, extPos - cutPos); 157 | string extension = replaceInclude.substr(extPos); 158 | string outFile = m_configHelper.m_solutionDirectory + m_projectName + "/" + filename + "_wrap" + extension; 159 | string newOutFile; 160 | m_configHelper.makeFileProjectRelative(outFile, newOutFile); 161 | // Check hasn't already been included as a wrapped object 162 | if (find(existingIncludes.begin(), existingIncludes.end(), newOutFile) != existingIncludes.end()) { 163 | // skip this item 164 | outputInfo(newOutFile); 165 | continue; 166 | } 167 | // Find the file in the original list 168 | string origName; 169 | for (auto& include : m_replaceIncludes) { 170 | if (include.first.find(filename) != string::npos) { 171 | origName = include.first; 172 | break; 173 | } 174 | } 175 | if (origName.length() == 0) { 176 | outputError("Could not find original file name for source file (" + filename + ")"); 177 | return false; 178 | } 179 | // Get the files dynamic config requirement 180 | string idents; 181 | bool isStatic = false; 182 | bool isShared = false; 183 | bool is32 = false; 184 | bool is64 = false; 185 | bool hasOther = false; 186 | for (auto include = m_replaceIncludes[origName].begin(); include < m_replaceIncludes[origName].end(); 187 | ++include) { 188 | idents += *include; 189 | if ((include + 1) < m_replaceIncludes[origName].end()) { 190 | idents += " || "; 191 | } 192 | if (*include == "ARCH_X86_32" || *include == "!ARCH_X86_64") { 193 | is32 = true; 194 | } else if (*include == "ARCH_X86_64" || *include == "!ARCH_X86_32") { 195 | is64 = true; 196 | } else if (*include == "CONFIG_SHARED" || *include == "!CONFIG_STATIC") { 197 | isShared = true; 198 | } else if (*include == "CONFIG_STATIC" || *include == "!CONFIG_SHARED") { 199 | isStatic = true; 200 | } else { 201 | hasOther = true; 202 | } 203 | } 204 | // Check if already a conditional file 205 | auto j = conditionalIncludes.find(replaceInclude); 206 | if (j != conditionalIncludes.end()) { 207 | if (hasOther) { 208 | conditionalIncludes.erase(j); 209 | } else if (j->second.isStatic != isStatic || j->second.isShared != isShared || j->second.is32 != is32 || 210 | j->second.is64 != is64) { 211 | outputError("Duplicate conditional files found with different conditions (" + replaceInclude + ")"); 212 | // TODO: Remove and make wrapped 213 | return false; 214 | } else { 215 | // skip this item 216 | continue; 217 | } 218 | } 219 | // Check for config requirement that can be handled by VS (i.e. static/shared|32/64bit) 220 | if ((isShared || isStatic || is32 || is64) && !hasOther) { 221 | conditionalIncludes.emplace(replaceInclude, ConfigConds(isStatic, isShared, is32, is64)); 222 | continue; 223 | } 224 | // Create new file to wrap input object 225 | string prettyFile = "../" + replaceInclude; 226 | string newFile = getCopywriteHeader(filename + extension + " file wrapper for " + m_projectName); 227 | newFile += "\n\ 228 | \n\ 229 | #include \"config.h\"\n"; 230 | if (m_configHelper.m_configComponentsStart > 0 && extension != ".asm") { 231 | newFile += "#include \"config_components.h\"\n"; 232 | } 233 | newFile += "#if " + idents + "\n\ 234 | # include \"" + 235 | prettyFile + "\"\n\ 236 | #endif"; 237 | // Check if assembly file 238 | if (extension == ".asm") { 239 | replace(newFile.begin(), newFile.end(), '#', '%'); 240 | findAndReplace(newFile, ".h", ".asm"); 241 | findAndReplace(newFile, "/**", ";"); 242 | findAndReplace(newFile, " */", ";"); 243 | findAndReplace(newFile, " *", ";"); 244 | } 245 | // Write output project 246 | if (!makeDirectory(m_configHelper.m_solutionDirectory + m_projectName)) { 247 | outputError("Failed creating local " + m_projectName + " directory"); 248 | return false; 249 | } 250 | if (!writeToFile(outFile, newFile)) { 251 | return false; 252 | } 253 | // Add the new file to list of objects 254 | existingIncludes.push_back(newOutFile); 255 | } 256 | return true; 257 | } 258 | 259 | bool ProjectGenerator::findProjectFiles(const StaticList& includes, StaticList& includesC, StaticList& includesCPP, 260 | StaticList& includesASM, StaticList& includesH, StaticList& includesRC, StaticList& includesCU, 261 | StaticList& includesCL, StaticList& includesCOMP) const 262 | { 263 | for (const auto& include : includes) { 264 | string retFileName; 265 | if (findSourceFile(include, ".c", retFileName)) { 266 | // Found a C file to include 267 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 268 | if (find(includesC.begin(), includesC.end(), retFileName) != includesC.end()) { 269 | // skip this item 270 | continue; 271 | } 272 | includesC.push_back(retFileName); 273 | } else if (findSourceFile(include, ".cpp", retFileName)) { 274 | // Found a C++ file to include 275 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 276 | if (find(includesCPP.begin(), includesCPP.end(), retFileName) != includesCPP.end()) { 277 | // skip this item 278 | continue; 279 | } 280 | includesCPP.push_back(retFileName); 281 | } else if (findSourceFile(include, ".asm", retFileName)) { 282 | // Found a ASM file to include 283 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 284 | if (find(includesASM.begin(), includesASM.end(), retFileName) != includesASM.end()) { 285 | // skip this item 286 | continue; 287 | } 288 | includesASM.push_back(retFileName); 289 | } else if (findSourceFile(include, ".h", retFileName)) { 290 | // Found a H file to include 291 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 292 | if (find(includesH.begin(), includesH.end(), retFileName) != includesH.end()) { 293 | // skip this item 294 | continue; 295 | } 296 | includesH.push_back(retFileName); 297 | } else if (findSourceFile(include, ".rc", retFileName)) { 298 | // Found a resource file to include 299 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 300 | if (find(includesRC.begin(), includesRC.end(), retFileName) != includesRC.end()) { 301 | // skip this item 302 | continue; 303 | } 304 | includesRC.push_back(retFileName); 305 | } else if (include.find(".ptx") != string::npos) { 306 | // Found a CUDA file 307 | string fileName = include.substr(0, include.find(".ptx")); 308 | if (findSourceFile(fileName, ".cu", retFileName)) { 309 | // Found a H File to include 310 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 311 | if (find(includesCU.begin(), includesCU.end(), retFileName) != includesCU.end()) { 312 | // skip this item 313 | continue; 314 | } 315 | includesCU.push_back(retFileName); 316 | } 317 | } else if (findSourceFile(include, ".cl", retFileName)) { 318 | // Found a opencl shader file to include 319 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 320 | if (find(includesCL.begin(), includesCL.end(), retFileName) != includesCL.end()) { 321 | // skip this item 322 | continue; 323 | } 324 | includesCL.push_back(retFileName); 325 | } else if (findSourceFile(include, ".comp", retFileName)) { 326 | // Found a compute shader file to include 327 | m_configHelper.makeFileProjectRelative(retFileName, retFileName); 328 | if (find(includesCOMP.begin(), includesCOMP.end(), retFileName) != includesCOMP.end()) { 329 | // skip this item 330 | continue; 331 | } 332 | includesCOMP.push_back(retFileName); 333 | } else { 334 | outputError("Could not find valid source file for object (" + include + ")"); 335 | return false; 336 | } 337 | } 338 | return true; 339 | } 340 | -------------------------------------------------------------------------------- /source/project_generate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * copyright (c) 2017 Matthew Oliver 3 | * 4 | * This file is part of ShiftMediaProject. 5 | * 6 | * ShiftMediaProject is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * ShiftMediaProject is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with ShiftMediaProject; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "configGenerator.h" 22 | #include "projectGenerator.h" 23 | 24 | int main(const int argc, char** argv) 25 | { 26 | outputLine("Project generator (this may take several minutes, please wait)..."); 27 | // Pass the input configuration 28 | ProjectGenerator projectGenerator; 29 | if (!projectGenerator.m_configHelper.passConfig(argc, argv)) { 30 | projectGenerator.errorFunc(false); 31 | } 32 | 33 | // Delete any previously generated files 34 | projectGenerator.m_configHelper.deleteCreatedFiles(); 35 | projectGenerator.deleteCreatedFiles(); 36 | 37 | // Output config.h and avutil.h 38 | if (!projectGenerator.m_configHelper.outputConfig()) { 39 | projectGenerator.errorFunc(); 40 | } 41 | 42 | // Generate desired configuration files 43 | if (!projectGenerator.passAllMake()) { 44 | projectGenerator.errorFunc(); 45 | } 46 | outputLine("Completed Successfully"); 47 | #if _DEBUG 48 | pressKeyToContinue(); 49 | #endif 50 | exit(0); 51 | } 52 | -------------------------------------------------------------------------------- /templates/template_files.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /templates/template_in.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | VisualStudioVersion = 12.0.30501.0 4 | MinimumVisualStudioVersion = 12.0.30501.0 5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{33ACD422-DFB7-46FF-8734-7031CCFF9247}" 6 | ProjectSection(SolutionItems) = preProject 7 | readme.txt = readme.txt 8 | EndProjectSection 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | DebugDLL|x64 = DebugDLL|x64 15 | DebugDLL|x86 = DebugDLL|x86 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | ReleaseDLL|x64 = ReleaseDLL|x64 19 | ReleaseDLL|x86 = ReleaseDLL|x86 20 | ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64 21 | ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(NestedProjects) = preSolution 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /templates/template_in.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {B4824EFF-C340-425D-A4A8-E2E02A71A7AE} 5 | template_shin 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 14 | .\;..\;%(AdditionalIncludeDirectories) 15 | /Qvec- /Qsimd- %(AdditionalOptions) 16 | /utf-8 %(AdditionalOptions) 17 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 18 | stdc11 19 | 20 | 21 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 22 | 23 | 24 | .\;..\;%(AdditionalIncludeDirectories) 25 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 26 | 27 | 28 | 29 | 30 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 31 | .\;..\;%(AdditionalIncludeDirectories) 32 | /Qvec- /Qsimd- %(AdditionalOptions) 33 | /utf-8 %(AdditionalOptions) 34 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 35 | stdc11 36 | 37 | 38 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 39 | 40 | 41 | .\;..\;%(AdditionalIncludeDirectories) 42 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 43 | 44 | 45 | 46 | 47 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 48 | .\;..\;%(AdditionalIncludeDirectories) 49 | /Qvec- /Qsimd- %(AdditionalOptions) 50 | /utf-8 %(AdditionalOptions) 51 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 52 | stdc11 53 | 54 | 55 | .\template_in.def 56 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 57 | 58 | 59 | .\;..\;%(AdditionalIncludeDirectories) 60 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 61 | 62 | 63 | 64 | 65 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 66 | .\;..\;%(AdditionalIncludeDirectories) 67 | /Qvec- /Qsimd- %(AdditionalOptions) 68 | /utf-8 %(AdditionalOptions) 69 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 70 | stdc11 71 | 72 | 73 | .\template_in.def 74 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 75 | 76 | 77 | .\;..\;%(AdditionalIncludeDirectories) 78 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 79 | 80 | 81 | 82 | 83 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 84 | .\;..\;%(AdditionalIncludeDirectories) 85 | /Qvec- /Qsimd- %(AdditionalOptions) 86 | /utf-8 %(AdditionalOptions) 87 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 88 | stdc11 89 | 90 | 91 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 92 | 93 | 94 | .\;..\;%(AdditionalIncludeDirectories) 95 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 96 | 97 | 98 | 99 | 100 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 101 | .\;..\;%(AdditionalIncludeDirectories) 102 | /Qvec- /Qsimd- %(AdditionalOptions) 103 | /utf-8 %(AdditionalOptions) 104 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 105 | stdc11 106 | 107 | 108 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 109 | 110 | 111 | .\;..\;%(AdditionalIncludeDirectories) 112 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 113 | 114 | 115 | 116 | 117 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 118 | .\;..\;%(AdditionalIncludeDirectories) 119 | /Qvec- /Qsimd- %(AdditionalOptions) 120 | /utf-8 %(AdditionalOptions) 121 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 122 | stdc11 123 | 124 | 125 | .\template_in.def 126 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 127 | 128 | 129 | .\;..\;%(AdditionalIncludeDirectories) 130 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 131 | 132 | 133 | 134 | 135 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 136 | .\;..\;%(AdditionalIncludeDirectories) 137 | /Qvec- /Qsimd- %(AdditionalOptions) 138 | /utf-8 %(AdditionalOptions) 139 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 140 | stdc11 141 | 142 | 143 | .\template_in.def 144 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 145 | 146 | 147 | .\;..\;%(AdditionalIncludeDirectories) 148 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 149 | 150 | 151 | 152 | 153 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 154 | .\;..\;%(AdditionalIncludeDirectories) 155 | /Qvec- /Qsimd- %(AdditionalOptions) 156 | /utf-8 %(AdditionalOptions) 157 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 158 | stdc11 159 | 160 | 161 | .\template_in.def 162 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 163 | 164 | 165 | .\;..\;%(AdditionalIncludeDirectories) 166 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 167 | 168 | 169 | 170 | 171 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 172 | .\;..\;%(AdditionalIncludeDirectories) 173 | /Qvec- /Qsimd- %(AdditionalOptions) 174 | /utf-8 %(AdditionalOptions) 175 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 176 | stdc11 177 | 178 | 179 | .\template_in.def 180 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 181 | 182 | 183 | .\;..\;%(AdditionalIncludeDirectories) 184 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /templates/template_in.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {2f2c4a75-f563-4eda-81a8-99f05e978394} 6 | 7 | 8 | {9dcb9da6-1c85-40b9-b875-9bdf9575be2d} 9 | 10 | 11 | {e05e69ea-955c-4c2c-83f8-ff30c0007387} 12 | 13 | 14 | 15 | 16 | Resource Files 17 | 18 | 19 | -------------------------------------------------------------------------------- /templates/template_in_winrt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | VisualStudioVersion = 12.0.30501.0 4 | MinimumVisualStudioVersion = 12.0.30501.0 5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{33ACD422-DFB7-46FF-8734-7031CCFF9247}" 6 | ProjectSection(SolutionItems) = preProject 7 | readme.txt = readme.txt 8 | EndProjectSection 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | DebugDLL|x64 = DebugDLL|x64 15 | DebugDLL|x86 = DebugDLL|x86 16 | DebugDLLWinRT|x64 = DebugDLLWinRT|x64 17 | DebugDLLWinRT|x86 = DebugDLLWinRT|x86 18 | DebugWinRT|x64 = DebugWinRT|x64 19 | DebugWinRT|x86 = DebugWinRT|x86 20 | Release|x64 = Release|x64 21 | Release|x86 = Release|x86 22 | ReleaseDLL|x64 = ReleaseDLL|x64 23 | ReleaseDLL|x86 = ReleaseDLL|x86 24 | ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64 25 | ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86 26 | ReleaseDLLWinRT|x64 = ReleaseDLLWinRT|x64 27 | ReleaseDLLWinRT|x86 = ReleaseDLLWinRT|x86 28 | ReleaseDLLWinRTStaticDeps|x64 = ReleaseDLLWinRTStaticDeps|x64 29 | ReleaseDLLWinRTStaticDeps|x86 = ReleaseDLLWinRTStaticDeps|x86 30 | ReleaseWinRT|x64 = ReleaseWinRT|x64 31 | ReleaseWinRT|x86 = ReleaseWinRT|x86 32 | EndGlobalSection 33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(NestedProjects) = preSolution 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /templates/template_in_winrt.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {B4824EFF-C340-425D-A4A8-E2E02A71A7AE} 5 | template_shin 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 14 | .\;..\;%(AdditionalIncludeDirectories) 15 | /Qvec- /Qsimd- %(AdditionalOptions) 16 | /utf-8 %(AdditionalOptions) 17 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 18 | stdc11 19 | 20 | 21 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 22 | 23 | 24 | .\;..\;%(AdditionalIncludeDirectories) 25 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 26 | 27 | 28 | 29 | 30 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 31 | .\;..\;%(AdditionalIncludeDirectories) 32 | /Qvec- /Qsimd- %(AdditionalOptions) 33 | /utf-8 %(AdditionalOptions) 34 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 35 | stdc11 36 | 37 | 38 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 39 | 40 | 41 | .\;..\;%(AdditionalIncludeDirectories) 42 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 43 | 44 | 45 | 46 | 47 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 48 | .\;..\;%(AdditionalIncludeDirectories) 49 | /Qvec- /Qsimd- %(AdditionalOptions) 50 | /utf-8 %(AdditionalOptions) 51 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 52 | stdc11 53 | 54 | 55 | .\template_in.def 56 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 57 | 58 | 59 | .\;..\;%(AdditionalIncludeDirectories) 60 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 61 | 62 | 63 | 64 | 65 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;DEBUG;BUILDING_template_shin;%(PreprocessorDefinitions) 66 | .\;..\;%(AdditionalIncludeDirectories) 67 | /Qvec- /Qsimd- %(AdditionalOptions) 68 | /utf-8 %(AdditionalOptions) 69 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 70 | stdc11 71 | 72 | 73 | .\template_in.def 74 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 75 | 76 | 77 | .\;..\;%(AdditionalIncludeDirectories) 78 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 79 | 80 | 81 | 82 | 83 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 84 | .\;..\;%(AdditionalIncludeDirectories) 85 | /Qvec- /Qsimd- %(AdditionalOptions) 86 | /utf-8 %(AdditionalOptions) 87 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 88 | stdc11 89 | 90 | 91 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 92 | 93 | 94 | .\;..\;%(AdditionalIncludeDirectories) 95 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 96 | 97 | 98 | 99 | 100 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 101 | .\;..\;%(AdditionalIncludeDirectories) 102 | /Qvec- /Qsimd- %(AdditionalOptions) 103 | /utf-8 %(AdditionalOptions) 104 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 105 | stdc11 106 | 107 | 108 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 109 | 110 | 111 | .\;..\;%(AdditionalIncludeDirectories) 112 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 113 | 114 | 115 | 116 | 117 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 118 | .\;..\;%(AdditionalIncludeDirectories) 119 | /Qvec- /Qsimd- %(AdditionalOptions) 120 | /utf-8 %(AdditionalOptions) 121 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 122 | stdc11 123 | 124 | 125 | .\template_in.def 126 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 127 | 128 | 129 | .\;..\;%(AdditionalIncludeDirectories) 130 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 131 | 132 | 133 | 134 | 135 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 136 | .\;..\;%(AdditionalIncludeDirectories) 137 | /Qvec- /Qsimd- %(AdditionalOptions) 138 | /utf-8 %(AdditionalOptions) 139 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 140 | stdc11 141 | 142 | 143 | .\template_in.def 144 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 145 | 146 | 147 | .\;..\;%(AdditionalIncludeDirectories) 148 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 149 | 150 | 151 | 152 | 153 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 154 | .\;..\;%(AdditionalIncludeDirectories) 155 | /Qvec- /Qsimd- %(AdditionalOptions) 156 | /utf-8 %(AdditionalOptions) 157 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 158 | stdc11 159 | 160 | 161 | .\template_in.def 162 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 163 | 164 | 165 | .\;..\;%(AdditionalIncludeDirectories) 166 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 167 | 168 | 169 | 170 | 171 | _CRT_SUPPRESS_RESTRICT;_UCRT_NOISY_NAN;restrict=__restrict;HAVE_AV_CONFIG_H;_USE_MATH_DEFINES;BUILDING_template_shin;%(PreprocessorDefinitions) 172 | .\;..\;%(AdditionalIncludeDirectories) 173 | /Qvec- /Qsimd- %(AdditionalOptions) 174 | /utf-8 %(AdditionalOptions) 175 | 4244;4267;4018;4146;4028;4996;4090;4114;4308;4305;4005;4101;4554;4307;4273;4133;4544;4334;4293;4047;4703;%(DisableSpecificWarnings) 176 | stdc11 177 | 178 | 179 | .\template_in.def 180 | /IGNORE:4006,4221,4049,4217,4197,4099,4264 %(AdditionalOptions) 181 | 182 | 183 | .\;..\;%(AdditionalIncludeDirectories) 184 | _MSC_VER;BUILDING_template_shin;%(PreprocessorDefinitions) 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /templates/template_with_latest_sdk.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET PROJECT=template_in 4 | 5 | @REM Detect the newest available Windows SDK 6 | CALL :GetWindowsSdkVer 7 | 8 | @REM Open the project 9 | %PROJECT%.sln 10 | 11 | EXIT /B 0 12 | 13 | :GetWindowsSdkVer 14 | SET WindowsTargetPlatformVersion= 15 | 16 | IF "%WindowsTargetPlatformVersion%"=="" CALL :GetWin10SdkVer 17 | IF "%WindowsTargetPlatformVersion%"=="" CALL :GetWin81SdkVer 18 | EXIT /B 0 19 | 20 | :GetWin10SdkVer 21 | CALL :GetWin10SdkVerHelper HKLM\SOFTWARE\Wow6432Node > nul 2>&1 22 | IF errorlevel 1 CALL :GetWin10SdkVerHelper HKCU\SOFTWARE\Wow6432Node > nul 2>&1 23 | IF errorlevel 1 CALL :GetWin10SdkVerHelper HKLM\SOFTWARE > nul 2>&1 24 | IF errorlevel 1 CALL :GetWin10SdkVerHelper HKCU\SOFTWARE > nul 2>&1 25 | IF errorlevel 1 EXIT /B 1 26 | EXIT /B 0 27 | 28 | :GetWin10SdkVerHelper 29 | @REM Get Windows 10 SDK installed folder 30 | FOR /F "tokens=1,2*" %%i IN ('reg query "%1\Microsoft\Microsoft SDKs\Windows\v10.0" /v "InstallationFolder"') DO ( 31 | IF "%%i"=="InstallationFolder" ( 32 | SET WindowsSdkDir=%%~k 33 | ) 34 | ) 35 | 36 | @REM get windows 10 sdk version number 37 | SETLOCAL enableDelayedExpansion 38 | IF NOT "%WindowsSdkDir%"=="" FOR /f %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO ( 39 | @REM Skip if Windows.h is not found in %%i\um. This would indicate that only the UCRT MSIs were 40 | @REM installed for this Windows SDK version. 41 | IF EXIST "%WindowsSdkDir%include\%%i\um\Windows.h" ( 42 | SET result=%%i 43 | IF "!result:~0,3!"=="10." ( 44 | SET SDK=!result! 45 | IF "!result!"=="%VSCMD_ARG_WINSDK%" SET findSDK=1 46 | ) 47 | ) 48 | ) 49 | 50 | IF "%findSDK%"=="1" SET SDK=%VSCMD_ARG_WINSDK% 51 | ENDLOCAL & SET WindowsTargetPlatformVersion=%SDK% 52 | IF "%WindowsTargetPlatformVersion%"=="" ( 53 | EXIT /B 1 54 | ) 55 | EXIT /B 0 56 | 57 | :GetWin81SdkVer 58 | SET WindowsTargetPlatformVersion=8.1 59 | EXIT /B 0 60 | -------------------------------------------------------------------------------- /templates/templateprogram_in.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | --------------------------------------------------------------------------------