c++ - Conditionally include source file based on compiler version? -


we testing project setup requires include or exclude source file based on compiler's version. test project located on github @ crc-test. poc, developing process crc-32c since both intel , arm have it. later applied aes, clmul, sha, avx{2}, bmi{2}, armv7a neon, armv8, etc. (ms compilers support neon , armv8 through intrinsics).

the source file trying conditionally compile crc-simd.cpp. has implementations using sse4.2 intrinsics , armv8 intrinsics (crc.cpp provides generic, c++ implementation).

i added vcx project file @ crc-test.vcxproj. there itemgroup clcompile:

<itemgroup>   <clcompile include="main.cpp" >     <precompiledheader />   </clcompile>   <clcompile include="crc.cpp" >     <precompiledheader />   </clcompile>   <clcompile include="crc-simd.cpp" >     <precompiledheader />   </clcompile> </itemgroup> 

i need conditional <clcompile include="crc-simd.cpp" > says, "if cl.exe 15.00 or greater, include source file". in preprocessor check _msc_ver >= 1500. in msbuild think looking like:

<itemgroup condition="'$(cl_version)'>='15.00'" label="sse4.2 acceleration">   <clcompile include="crc-simd.cpp" >     <precompiledheader />   </clcompile> </itemdefinitiongroup> 

i found list of msbuild built-in variables, don't know $(cl_version) in real life. seraching "cl" did not result in interesting hits. found 1 question @ msbuild vs compiler, asking different question.

my question is, how reference cl.exe version in msbuild conditional?

a related problem is, need full version. example, aes support added @ vs2005 sp1, cl.exe version 15.00.30729 (_msc_full_ver >= 150030729). related question is, how reference cl.exe full version in msbuild conditional?


trying use following developer prompt:

<itemdefinitiongroup condition="'$(cl_version)'>='15.00'" label="sse4.2 acceleration">   <clcompile include="crc-simd.cpp" >     <precompiledheader />   </clcompile> </itemdefinitiongroup> 

results in:

> cls && msbuild  microsoft (r) build engine version 4.6.1087.0 [microsoft .net framework, version 4.0.30319.42000] copyright (c) microsoft corporation. rights reserved.  build started 7/25/2017 1:23:31 pm. project "c:\users\test\crc-test\crc-test.vcxproj" on node 1 (default ta rgets). c:\users\test\crc-test\crc-test.vcxproj(127,14): error msb4066: att ribute "include" in element <clcompile> unrecognized. done building project "c:\users\test\crc-test\crc-test.vcxproj" (defaul t targets) -- failed.  build failed.  "c:\users\test\crc-test\crc-test.vcxproj" (default target) (1) ->   c:\users\test\crc-test\crc-test.vcxproj(127,14): error msb4066: ttribute "include" in element <clcompile> unrecognized.      0 warning(s)     1 error(s)  time elapsed 00:00:00.11 

the project setup visual studio 2010. if using different version, change suite tastes. there no need vcupgrade:

<platformtoolset>v100</platformtoolset> 
  • vs2010 → v100
  • vs2012 → v110
  • vs2013 → v120
  • vs2015 → v130
  • vs2017 → v140

here essence of project on linux in gnumakefile. when compiler , platform support hardware acceleration, bring-in crc-simd.cpp file faster implementation. want msbuild.

has_armv8 ?= $(shell uname -m | $(egrep) -i -c 'aarch32|aarch64') has_sse42 ?= $(shell uname -m | $(egrep) -i -c 'amd64|x86_64|i*86') gcc43_or_later := $(shell $(cxx) -v 2>&1 | $(egrep) -i -c "gcc version (4\.[3-9]|[5-9]\.)") gcc48_or_later := $(shell $(cxx) -v 2>&1 | $(egrep) -i -c "gcc version (4\.[8-9]|[5-9]\.)") ...  objects = main.o crc.o  ifeq ($(has_armv8)$(gcc48_or_later),11) objects += crc-simd.o endif  ifeq ($(has_sse42)$(gcc43_or_later),11) objects += crc-simd.o endif ...  ifeq ($(has_armv8)$(gcc48_or_later),11) crc-simd.o : crc-simd.cpp     $(cxx) $(cxxflags) -march=armv8-a+crc -c $< endif  ifeq ($(has_sse42)$(gcc43_or_later),11) crc-simd.o : crc-simd.cpp     $(cxx) $(cxxflags) -msse4.2 -c $< endif ... 

a similar approach makefiles can used: run cl.exe, use regex version, include source file if version greater number. in code:

<target name="getclversion">   <!-- run cl, store output in variable -->   <exec command="cl.exe" consoletomsbuild="true" ignoreexitcode="true">     <output taskparameter="consoleoutput" propertyname="clout" />   </exec>   <propertygroup>     <!-- cl.exe version number 18.00.31101 -->     <clversion>$([system.text.regularexpressions.regex]::match('$(clout)','(\d+\.\d+\.\d+)'))</clversion>     <!-- turn integer 180031101 getting rid of dots -->     <clversion>$([system.string]::copy('$(clversion)').replace('.', ''))</clversion>   </propertygroup> </target>  <!-- run in build, before compilation,      can modify clcompile itemgroup. needs done      in target, else cannot use results other targets      (getclversion in case) --> <target name="showclversion" dependsontargets="getclversion"         beforetargets="buildgeneratesources">   <!-- &gt; = escaped > sign -->   <itemgroup condition="$(clversion) &gt; 180031100">     <clcompile include="somefile.cpp" />   </itemgroup> </target> 

notes: lists of built-in variables found msbuild, build system, sort of seperate compiler; that's why there's no cl_version makefile has no gcc_version default. it's worth trying use

<platformtoolset>$(defaultplatformtoolset)</platformtoolset> 

instead of sticking single 1 or keeping multiple projects, 1 each vs version. keeps vs asking upgrade (since sees it's default platform toolset being used). don't have vs versions < 2012 test if works there though, vs2012 , onwards that's 4 of them, , counting.


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -