What files belong to a build target in CDT managed build? - c++

In CDT's managed builder, how are individual files assigned to build configurations?
Specifically, how can I:
indicate that configuration A has to build and link sources from folders A and B, while configuraion B shall use folders A and C,
include sources (not headers) from a referenced project (or just any external source files?) to be also built and linked as a part of a given project?

1st point, assuming there are 3 folders A,B & C containing .cpp files, try this :
select folder C in the 'project explorer' pane, right-click > exclude from build... > check configuration A > ok
select folder B, right-click > exclude from build... > check configuration B > ok
This way configuration A will ignore .cpp files from folder C and configuration B will ignore folder B.
2nd point : maybe you could use import > general > file system to import source from an external folder into your project ?

Related

Can not open include file; no such file or dir

I created new solution and new project (further A), added another external project (further B) Right click -> add existing project. Now, I have two projects (A & B) in my solution. I added also additional dirs to project A in order to it can see headers of project B. Then I added a few imports in file or project A from project B.
Then if I make right click on project B -> Rebuild it is built without any errors, then if I make right click on project B -> Rebuild I got an error that says :
1>------ Build started: Project: _DecoderEngine, Configuration: Release x64 ------
1>TetStreamDecoder.cpp
1>D:\land\co_main\_Infrastructure\Tier1.0\_FileCodec\_Decoder\_IDecoderCallback.h(3): fatal error C1083: Cannot open include file: '_Shared/_FileTypes.h': No such file or directory
1>Done building project "_DecoderEngine.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========
What is weird that a file where I got an error it is a file from project B, it means if I make right click on project B -> Rebuild it is ok, but if I try rebuild project A that has import from B I got and error in files from project B...
What am I doing wrong? I feel like I miss something in configuration, maybe should I add something to Liker or something else?
EDIT
tree looks like this
FileCodec
|
-_DecoderEngine (project A)
|
-_Decoder (project B)
|
-_Shared
FYI - project A use project B and project B use Shared
Then, dependencies I have added to C\C++ -> Additional dirs to project A are :
../_Decoder
../_Shared
Looks ok, because Decoder engine reside on the same level in tree as dependency, so we need to go one level up and here you are.

Add OpenSSL static lib to Visual Studio 2017 project

Do NuGets modify the include and linking paths when added to a project?
My background is with CMake where this stuff was trivial, but I'm now at a company that builds solution files from the ground up and I'm unsure how to properly add the static OpenSSL libs to my project. I'm posting the question to make sure I don't duplicate something or otherwise mess it up.
When I add the openssl-vc141-static-x86_64 to my project, it builds the .lib files and everything, but does not modify the include or linker paths.
I can manually add the linker paths, but because the project I was given doesn't have the typical Release/Debug configurations, I can't use the $(Configuration) macro to point at the target libs - so I end of just pointing at Release. The build works though.
I see there is a .targets file, but it doesn't seem to do anything.
(update)
To be specific, I'm basically building boost's http_server_async.cpp. The linker errors I'm getting are:
Error LNK2019 unresolved external symbol _BIO_free referenced in function "public: __thiscall boost::asio::ssl::context::bio_cleanup::~bio_cleanup(void)" (??1bio_cleanup#context#ssl#asio#boost##QAE#XZ) ESOIPDataScope C:\gitrepo\ALIDB\ESOIPDataScope\DataHandler.obj
Error LNK2001 unresolved external symbol _BIO_free ESOIPDataScope C:\gitrepo\ALIDB\ESOIPDataScope\Listener.obj
... (48 more like this)
When I manually add $(SolutionDir)packages\openssl-vc141-static-x86_64.1.1.0\build\native\lib\Win32\static\Release\libcrypto.lib and
$(SolutionDir)packages\openssl-vc141-static-x86_64.1.1.0\build\native\lib\Win32\static\Release\libssl.lib to be additional dependencies the project compiles.
(/update)
Just for contrast, I added a freeglut NuGet, and noticed that gave my more configuration options (Configuration Properties → Referenced Projects), also, boost seems to have added its linker directories to my project (though I only see that in MSBuild output, not in Configuration Properties->Linker->Command Line)
Is there a proper way to add these projects that I'm missing? Or a proper way to use the targets file? Or maybe the OpenSSL static NuGet just missing something? Or maybe I should just look into vcpkg?
Do NuGets modify the include and linking paths when added to a
project?
Sure. I can tell you explicitly that the nuget imports additional properties into the project through <package_id>.targets or <package_id>.props file, instead of manually adding include path again.
This is a mechanism for nuget packaging to add additional project properties such as library path directly to the project during the installation of the nuget package. More info you can refer to this link.
The <package_id>.targets was created during the process of packing the nuget package.
In other words, this method was designed by the author of the nuget package. And in my side, the file openssl-vc141-static-x86_64.targets exists in this path:
C:\Users\Admin\source\repos\ConsoleApplication25\packages\openssl-vc141-static-x86_64.1.1.0\build\native
also, boost seems to have added its linker directories to my project
(though I only see that in MSBuild output, not in Configuration
Properties->Linker->Command Line)
l think the issue is related to the difference between <package_id>.targets and <package_id>.props. Although using <package_id>.targets does not appear on the property UI, it still works for the whole project.
In more detail
When you install the nuget package into the project, these files are automatically executed. <target_id>.props file is added at the top of the file while .targets is added at the bottom.
When initializing the xxx.vcxproj file, because <package_id> .props is at the head of the file, the property UI can capture the properties in the file, and <package_id> .targets is at the end, so the initialization cannot be captured but still In the project. For the nuget, it uses openssl-vc141-static-x86_64.targets.
In openssl-vc141-static-x86_64.targets file, you can see this:
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include\;%
(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAS_LIBTHRIFT;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
</ClCompile>
And l have set the output log to Diagnostic and build the project and found this:
The library path has been added into AdditionalIncludeDirectories by the openssl-vc141-static-x86_64.targets file automatically. So you do not have to worry about it.
Is there a proper way to add these projects that I'm missing? Or a
proper way to use the targets file? Or maybe the OpenSSL static NuGet
just missing something? Or maybe I should just look into vcpkg?
You do not need to worry about it and do not add the include path into project property. This is superfluous and when you have finished installing this nuget package, use it in cpp files directly.
In addition,
For c++ packages installed by nuget, you don't need to add any paths to the project property.
Update 1
The issue is related to your project rather than the nuget package. Exactly because your current project does not have $(Configuration), so in openssl-vc141-static-x86_64.targets, you can see these:
<ItemDefinitionGroup Label="Win32 and vc141 and Debug" Condition="'$(Platform)' == 'Win32' And ( $(PlatformToolset.IndexOf('v141')) > -1 Or '$(PlatformToolset)' == 'WindowsKernelModeDriver8.0' Or '$(PlatformToolset)' == 'WindowsApplicationForDrivers8.0' Or '$(PlatformToolset)' == 'WindowsUserModeDriver8.0' ) And '$(Configuration)' == 'Debug'">
<Link>
<AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)lib\Win32\static\Debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libssl.lib;libcrypto.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y "$(MSBuildThisFileDirectory)\lib\Win32\dynamic\*-1_1.dll" "$(OutDir)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
This is the operation to import specific libssl.lib and libcrypto.Lib into the AdditionalDependencies node. But you can find out that there is a judge condition And '$(Configuration)' == 'Debug', since you do not have $(Configuration),therefore, it always returns false and these libs cannot be automatically imported into AdditionalDependencies.
As a workaround, you should add these lib path manually just as you said.
And l am sure that if you use a project which contains $(Configuration)(Debug or Release), you will not encouter this issue. And most of the C++ nuget packages can be used directly in the project which contains the Configuration node.
l am sure that if you use the $(Configuration) into your project and then reinstall this package(please clean the nuget cache before doing it), you will not face this error.
Also, your screen shot, where did you get that? I don't see anything
like that in the VS output console, or when I run msbuild on the
command line. Is there some way I might have accidentally broken the
default behaviour?
You can set MSBuild project build output verbosity to Diagnostic by Tools-->Options-->Projects and Solutions-->Build and Run.
When you build your project,the Output Window shows thw whole build process and records all the information and then you can search the key fields by the search box on the Output Window.

How to struct project files for the correct build

Suppose I have the next projects structure (to be more convient let assume that QtCreator is used as IDE):
|
|-build_minGW
|-build_msvs
|-...
|-Project
|-src
|-inc
|-...
Moreover, suppose I want to use some .json files to store settings of my program. So after every compilation program should be run from the respective 'build' folder. Where should I create this .json files (Project folder, 'build' folder or elsewhere)? Is it any common and correct way to do this automaticaly (e.g. if I create files in Project folder, they should be copied to the every build directory)?

Separate dll from other output files in c++ projects

I have a few dll projects in a solution (some depending on each other)
Project1 -> Properties -> Linker -> Input -> Additional Dependencies -> Project2.lib
Project1 -> Properties -> Linker -> General -> Additional Library Directories -> $(OutDir)
All is working fine.
Projects are Win7Debug Win32, Win7Debug x64..... and a Win32 project with only Debug and Release configurations.
I would like to have all dll's for Win32 placed in one folder and the x64 ones in another folder. So I added the x64 configuration for the Win32 project, and changed
Project1 -> Properties -> Linker -> General -> Output File -> $(SolutionDir)/i386/$(TargetName)/$(TargetExt)
(for Win32 - similar change for x64)
all seemed fine - and I only received dlls in the i386 folder... until I had to rebuild and got
Warning 23 warning MSB8012:
TargetPath(C:\Path\Win7Debug\Project1.dll) does not match the Linker's OutputFile
property value (C:\Path\i386\Project1.dll). This may cause your project to build
incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and
$(TargetExt) property values match the value specified in %(Link.OutputFile).
This seems serious... and I don't want to have problems with missing dependencies (though everything seems to be working fine - and not just on my machine)
I changed
Project1 -> Properties -> Configuration Properties -> General -> OutputDirectory -> $(SolutionDir)/i386
(to match the linker output) but now of course I get lib and exp files in the same folder as the dll's.
Other than using post build script, is there a way to separate the output files ?
Should I just leave the settings how I had them and disregard the warning above ?
Note: I am not trying to separate the Platform/configuration output files... That is done automagically using the default output directory.
What I need is, for each platform, to place only DLL files in one folder away from anything else. Redirecting Linker output (and leaving project output to standard) accomplishes that - I just am not sure if it is correct. Logically I should not have any build problems since I am giving linker all the info it needs...
The standard approach is to leave all these properties unchanged (inherit from parent). In this case linker will create DLL and LIB in $(Output) directory, which by default is $(SolutionDir)$(Configuration).
You just specify the name for x64 configuration, and all output files will be separated automatically.
The standard (and the easest) way to link import library is to add reference to corresponding project in Common Properties / References page. Nothing else is required.
If, for any reason, it is impossible, add $(SolutionDir)$(Configuration) to Configuration Properties / VC++ Directories / Library Directories and add library to be linked to Linker / Additional Dependencies. If there are many projects in your solution, you may create Property Sheet for the solution and specify Library Directories only once.

Visual Studio 2010 project file filters

I have a complex C/C++ bunch of applications that I'm working on which is supposed to also be platform independent. So far, is UNIX/Windows compatible and it runs fine. However, maintaing this monster on VS2010 is a nightmare. I have the following file structure:
/
sources
lib1
include
...
src
...
lib2
include
...
src
...
app3
include
...
src
...
builders
cmake
...
make
...
VS2010
vs2010.sln
lib1
lib1.vcxproj
lib1.vcxproj.filters
lib2
lib2.vcxproj
lib2.vcxproj.filters
app3
app3.vcxproj
app3.vcxproj.filters
As we can see, because everything is platform independent, I had to completely separate the builders from sources. IMHO, that itself is a very good practice and it should be enforced by everyone :)
Here is the problem now... VS2010 is completely unusable when it comes to organize the include/sources files in filters. You have to do that manually by repeatedly doing "Add -> New Filter" followed by "Add -> Exiting Item". I have a VERY complex folder structure and files in each and every include folder. The task for creating the filters becomes a full day job. On the other hand, I could just drag the whole folder from Explorer onto the project inside VS2010 but it will put all header/source files in there without any filters, rendering it worthless: you can't possible search within 100 files for the right one without having some sort of hierarchy..
Question is:
Is VS2010 having some obscure way of importing a folder AND preserving the folder structure as filters? Looks to me that M$FT people who created VS2010 think that M$FT is the only animal in the jungle and you MUST pollute the sources folder with builders projects so you can leverage "show hiden files" to include them in the project along with the folder structure. That is absurd IMHO...
You are using CMake, so I advise you stick with only this. You can generate makefiles and VS2010 project files with it (at least). For VS, the generated files are a sln and a bunch of vxproj (one for each project in the CMake script).
In CMake file you can group files, using the command source_group. The filters will be automatically generated for vs according to the source groups. I don't know for other IDE like Code::Blocks or NetBeans.
If you want automatic grouping based on file path [Comment request]:
# Glob all sources file inside directory ${DIRECTORY}
file(GLOB_RECURSE TMP_FILES
${DIRECTORY}/*.h
${DIRECTORY}/*.cpp
${DIRECTORY}/*.c
)
foreach(f ${TMP_FILES})
# Get the path of the file relative to ${DIRECTORY},
# then alter it (not compulsory)
file(RELATIVE_PATH SRCGR ${DIRECTORY} ${f})
set(SRCGR "Something/${SRCGR}")
# Extract the folder, ie remove the filename part
string(REGEX REPLACE "(.*)(/[^/]*)$" "\\1" SRCGR ${SRCGR})
# Source_group expects \\ (double antislash), not / (slash)
string(REPLACE / \\ SRCGR ${SRCGR})
source_group("${SRCGR}" FILES ${f})
endforeach()