18

I'm trying to add additional paths to be used by my project group during compilation. Since C++ Builder 2010 uses msbuild I have tried looking at the documentation for that and according to what I can find AdditionalLibPaths should be passable as a property. i.e

msbuild /p:AdditionalLibPaths=C:\FooBar\Libs /t:build foo.groupproj

But it doesn't seem to use the paths I added. I have previously noticed that some property names differ between VC++ and C++ Builder when passed to msbuild and wonder if C++ Builder might use some other property name to add additional lib and include folders?

I don't want to replace the existing paths defined in the project but append additional ones. The rationale for this is that when the project is build on our build server some libraries reside in a standardized place that might differ from where it's installed on the development machine.

msbuild acutally calls a msbuild script file that in turn calls additional scripts including the .groupproj ones using the tag. I know that a new instance of msbuild is created when using the tag so I know that I have to add the property when running that task in my script.

<MSBuild Targets="Build" Projects="..\Foo.groupproj" Properties="Config=Debug (property to add additional paths here!)" />

Update:

C++ Builder seems to be using IncludePath and ILINK_LibraryPath but setting these overwrite the paths already defined in the project file. Since this file is created and maintained by the IDE so any changes to make it append instead of overwrite would be overwritten by the IDE. Which is kind of strange since it looks like it should indeed append the values

<IncludePath>..\FooBar\;$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;Common Components;..\Config\Config32;$(IncludePath)</IncludePath>

Update 2:

In CodeGear.Cpp.Targets I added my own property called AdditionalIncludePaths to the PropertyGroup fiddling with the include paths.

Around line 251

<PropertyGroup>
        <BCC_NoLink>true</BCC_NoLink>
        <ILINK_OSVersion Condition="'$(ILINK_OSVersion)'=='' And '$(NoVCL)'!='true'">5.0</ILINK_OSVersion>
        <DCC_GenerateCppFiles>true</DCC_GenerateCppFiles>
        <ShowStdOut Condition="'$(ShowStdOut)'==''">$(ShowGeneralMessages)</ShowStdOut>

        <!-- _TCHAR mapping for Uni^H^H^H character selection -->
        <StartupObj Condition="'$(_TCHARMapping)'=='wchar_t'">$(StartupObj)w</StartupObj>
        <ILINK_StartupObjs Condition="'$(ILINK_StartupObjs)'==''">$(StartupObj)</ILINK_StartupObjs>
        <BCC_GenerateUnicode Condition="'$(_TCHARMapping)'=='wchar_t'">true</BCC_GenerateUnicode>
        <!-- Include Paths -->
        <Win32LibraryPath Condition="'$(Win32LibraryPath)'==''">$(BDS)\lib</Win32LibraryPath>
        <IncludePath Condition="'$(CBuilderIncludePath)'!=''">$(IncludePath);$(CBuilderIncludePath)</IncludePath>
                <IncludePath Condition="'$(AdditionalIncludePath)'!=''">$(IncludePath);$(AdditionalIncludePath)</IncludePath>
        <BCC_IncludePath Condition="'$(BCC_IncludePath)'!=''">$(BCC_IncludePath);$(IncludePath)</BCC_IncludePath>
        <BCC_IncludePath Condition="'$(BCC_IncludePath)'==''">$(IncludePath)</BCC_IncludePath>
        <BRCC_IncludePath Condition="'$(BRCC_IncludePath)'!=''">$(BRCC_IncludePath);$(IncludePath)</BRCC_IncludePath>
        <BRCC_IncludePath Condition="'$(BRCC_IncludePath)'==''">$(IncludePath)</BRCC_IncludePath>
        <DCC_IncludePath Condition="'$(DCC_IncludePath)'!=''">$(DCC_IncludePath);$(IncludePath)</DCC_IncludePath>
        <DCC_IncludePath Condition="'$(DCC_IncludePath)'==''">$(IncludePath)</DCC_IncludePath>
        <DCC_UnitSearchPath>$(DCC_IncludePath);$(Win32LibraryPath)</DCC_UnitSearchPath>
        <DCC_ResourcePath>$(DCC_IncludePath)</DCC_ResourcePath>
        <DCC_ObjPath>$(DCC_IncludePath)</DCC_ObjPath>
        <TASM_IncludePath Condition="'$(TASM_IncludePath)'!=''">$(TASM_IncludePath);$(IncludePath)</TASM_IncludePath>
        <TASM_IncludePath Condition="'$(TASM_IncludePath)'==''">$(IncludePath)</TASM_IncludePath>

Then I can call

msbuild /t:build /p:AdditionalIncludePaths=C:\Foo\Include foo.groupproj

This works fine and does what I want. I'll just have to do the same with the library paths. But I don't want to have to hack one of Embarcaderos supplied files like this. That's just ridiculous :P... Isn't there any official property to set for adding include paths and lib paths?

inquam
  • 12,664
  • 15
  • 61
  • 101

4 Answers4

11

For VS2013, just define environment variables before running msbuild:

set "INCLUDE=%additional_include_path%;%INCLUDE%"
set "LIB=%additional_lib_path%;%LIB%"
REM use environment variables for INCLUDE and LIB values
set UseEnv=true

Reference: MSBuild/Microsoft.Cpp/v4.0/V120/Microsoft.Cpp.targets

<Target Name="SetBuildDefaultEnvironmentVariables"
        Condition="'$(UseEnv)' != 'true'">
...
    <SetEnv Name   ="INCLUDE"
        Value  ="$(IncludePath)"
        Prefix ="false" >
       <Output TaskParameter="OutputEnvironmentVariable"             PropertyName="INCLUDE"/>
    </SetEnv>

But looks like the INCLUDE and LIB appended behind additional include/lib directories specified in project properties.

zhifac
  • 111
  • 1
  • 5
6

For additionals include on VS2019, use the switch /p:IncludePath=C:\Foo

To include multiple paths, use double quote and semi-colon on the switch:

/p:IncludePath="C:\Foo;C:\Bar;C:\Another;$(IncludePath)"
flydev
  • 4,327
  • 2
  • 31
  • 36
3

In C++Builder 10 Seattle (current version as of 2016), I was able to solve this problem (i.e. add custom library paths in automated build) by putting additional library paths into environment variable ILink_LibraryPath before running msbuild. This has to be done by set ILink_LibraryPath=..., not by passing property as /p:... to msbuild.

This achieves additional paths in automated build environment, without replacing existing paths already set in .cbproj files, and doesn't require any hacks in Embarcadero-supplied files.

The only problem with this approach is that the sequence in which individual paths are checked is not guaranteed - i.e. custom paths supplied via environment variable are appended to .cbproj paths or possibly put in the middle, depending on project setup, and are not necessarily put in front, so you need to be careful to not have conflicting libraries in other directories mentioned in project files.

Cozzamara
  • 1,318
  • 1
  • 14
  • 22
  • Very useful answer, thanks! Regarding this environment variable, in case we need to provide more than one value paths then how would the syntax look like? –  May 08 '17 at 13:54
  • @nk-fford separate multiple paths with semicolon – Cozzamara May 11 '17 at 05:49
1

For VS2019, I have test msbuild that it will not apply these environment variables of INCLUDE and LIB, even you have set them. The underlying reason may be that msbuild overwirte INCLUDE and LIB when loading and compiling *.sln or *.vcxproj. However, it just my suppostion as online documentions about windows/msbuild is very poor to find the underhood reason.

Solution A:
In my solution, I use CL and LINK environment variables to set the include directory and the lib directory before msbuild building the project as:

set $env:CL="/I\C:\users\user\local\include"
set $env:LINK="/LIBPATH:C:\users\user\local\lib"
...
msbuild *.vcxproj

more about CL at MSVC compiler environment variables
more about LINK at MSVC Linker environment variables

Solution B:
for another possible solution as you have already pointed, you can pass options to msbuild like:

msbuild *.vcxproj /nologo /p:AdditionalIncludePaths="C:\users\user\local"
msbuild *.vcxproj /nologo /p:IncludePath="C:\users\user\local"
liviaerxin
  • 579
  • 6
  • 13