Generating a custom ItemGroup in .vxcproj using CMake - visual-studio

I'm trying to use CMake to add an entire directory structure to my Visual Studio project. I know it is possible in VS because I already succeed by manually copying the root folder of the structure in the same directory of the project and by selecting "Include in Project". However, I'm not sure that it would be possible with CMake.
My .vcxproj contains this ItemGroup after this manual operation:
<ItemGroup>
<Text Include="asd\test.txt" />
<Text Include="asd\asd2\test.txt" />
</ItemGroup>
As you can see I just added two folders and two txt files. This produces the result I'm trying to achieve.
Any idea on how to generate this with CMake?

CMake is meant to hide the details of the build/OS environment from the user. This requires some generalization across platforms/environments. So it's difficult to get an exact copy of a manual made .vcxproj project.
You can add any files to CMake targets - explicitly including none-source files - that will then be added by CMake to generated IDE projects.
If I understand your particular case correctly the problem is to get Text instead of None tool name in ItemGroup source file's listing.
Since CMake version 3.7 you can use VS_TOOL_OVERRIDE source files property to override CMake's default for non-source files.
The following small example:
cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
file(WRITE main.cpp [=[
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
}
]=])
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/asd/test.txt" "")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/asd/asd2/test.txt" "")
add_executable(HelloWorld "main.cpp" "asd/test.txt" "asd/asd2/test.txt")
set_source_files_properties(
"asd/test.txt"
"asd/asd2/test.txt"
PROPERTIES VS_TOOL_OVERRIDE "Text"
)
Does give your expected results. CMake just generates absolute paths by default.
Reference
C++ CMake (add non-built files)

Related

Have Intermediate CMake Files Appear in the IDE

I am developing a system of build scripts for CMake and have an issue with wanting to have intermediate CMakeLists.txt files appear in the IDE for easier search and edit.
I have a main CMake file that includes a directory that includes several subdirectories for libraries.
CMakeLists.txt
--- SubProjects:
-------CMakeLists.txt
-------ProjectAFolder:
----------CMakeLists.txt
-------ProjectBFolder:
----------CMakeLists.txt
-------ProjectCFolder:
----------CMakeLists.txt
In the SubProjects folder, the CMakeLists.txt is very simple and just includes the subproject folders one after the other:
SET(SUBDIRECTORIES ProjectAFolder
ProjectBFolder
ProjectCFolder )
foreach (subdirectory ${SUBDIRECTORIES})
add_subdirectory(${subdirectory})
endforeach ()
However, when I generate this in XCode or Visual Studio, the IDE does not include the intermediate CMakeLists.txt file anywhere because it does not belong to any individual library or executable target. What is the best way to include this somewhere so it appears in an IDE?
Depends on where you want the file to show up, since it doesn't belong to any target. You can simply add it to any existing target (just as you do with source files) or you can create a new custom target.
add_library(AnyExistingTarget <other source files> SubProjects/CMakeLists.txt)
Or create a custom target:
add_custom_target(MyIntermediateCMakeFiles SubProjects/CMakeLists.txt)
For Visual Studio, you could also use the built-in support for cmake. It will display the source tree in the IDE without any extra work.

Importing a .props file in .vcxproj generated by qmake

With a command
qmake -tp vc -r
I'm generating Visual Studio .sln file and a bunch of .vcxproj files from corresponding Qt .pro file and a bunch of .pri files.
I would like those generated .vcxproj files to import my own .props file. A path to which I can provide to qmake or embed it in those .pro/.pri files.
Is it possible? If so then how?
Since by my research it seems that this can by only done by adding a custom extension (which I would have to write first...) to mkspecs...
Judging by qmake source code, it's not possible. I've looked into qmake\generators\win32\msbuild_objectmodel.cpp in both Qt4.8.5 and latest Qt5 version, and the only Property Sheets that are added by qmake are Microsoft.Cpp.*.props (of various kinds):
xml << tag("Import")
<< attrTag("Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props")
<< attrTag("Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')")
<< closetag()
<< closetag();
I have solved this problem by creating a quick Python script, that does the post-processing on the generated *.vcxproj files:
for l in fileinput.FileInput('Project.vcxproj', inplace=1):
print l,
if 'PropertySheets' in l:
print ' <Import Project="YourPropertySheets.props" />'
Of course, it would be better to patch the qmake with the new functionality, but since there are only three people including you and me that are bothered with this, I believe the hack to be the optimal solution.

How to compile the header file with Q_OBJECT macro in Xcode?

I create C++ project in Xcode which links against the Qt framework. The hello world program works well. When I add a class derived from QObject and add the Q_OBJCET macro, there is link error.
The class is
MyObject.h
#ifndef MyObject_h
#define MyObject_h
#include <QtCore/QObject>
class MyOBject : public QObject
{
Q_OBJECT
public:
MyOBject();
};
#endif
MyObject.cpp
#include "MyObject.h"
MyOBject::MyOBject()
{
}
I know I should use the moc to compile the MyObject.h first and add the generated moc_MyObject.cpp to the Xcode project.
In Microsoft Visual Studio, I can configure this header file to be compiled with moc custom tool. And add the generate cpp file to VS project.
But this is Xcode. My question is: Is there equivalent mean in Xcode to compile the header file including Q_OBJECT macro?
Here's how you do it in Xcode 6:
Select your target and in Build Rules make a new custom rule.
Set the "Process" drop down to "Source files with names matching" and type in *.h next to that.
Set the "Using" drop down to "Custom script:" and in the script type something close to this:
/path/to/your/Qt/bin/moc ${INPUT_FILE_PATH} -o ${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}_moc.cpp
You'll have to change the path to wherever your moc executable is.
Now set the "Output files" to:
${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}_moc.cpp
That's it for the Custom Rule.
Now to get the headers to be compiled with this rule. While your target is still selected go to "Build Phases". Expand the "Compile Sources" section, hit the "+" button at the bottom. Find and add the header files with Q_OBJECT classes in them. Add those headers to your project first if you can't find them in there.
That's it, Xcode will then run moc on those headers and it will understand that the output from moc is a .cpp and needs to be compiled and linked into you app and do that for you.
I didn't find how to set the custom tool for a specific header file in Xcode. I found a workaround via the build phase script (Build Phases -> Add Build Phase -> Add Run Script). I added the moc command line as script, and included the generated moc_MyObject.cpp file to MyObject.cpp. It works now.

Customize building VC++ in VS2010

I have a big C++ project and I need to do many steps in the building phase because I am building an application that is compatible with both 64 and 32, I have three projects:
proj1,Porj2,Proj3
and I need to do the following:
Exclude a cpp File from proj1 (32bit version)
Include a cpp file to proj1 (64bit version)
build proj1
build proj2
Execute output of proj2
Exclude a cpp File from proj3 (32bit version)
Include a cpp file to proj3 (64bit version)
Build proj3
Rename the exe that was built from proj3
Exclude a cpp File from proj1 (64bit version)
Include a cpp file to proj1 (32bit version)
still there are some other steps ... I was doing that manually and its frustrating, I found the I need to use MSBUILD but is it used for building native code ? and how can I perfrom these tasks ?
-Excluding and Including cpp files into projects
-Building proj
In Visual Studio 2010 and later, C++ projects use MSBuild.
Rather than excluding or including files based on the configuration, it would be simpler to use a preprocessor directive to conditionally compile the contents of the file. E.g., wrap the entire contents of the file in:
#ifdef MY_32BIT_BUILD_MACRO
// Source file contents here
#endif
And likewise with a macro for 64-bit builds. When using Visual C++, you can use the _M_IX86 and _M_X64 predefined macros to detect whether you are compiling for x86 or x64, respectively.
Alternatively, you could add a Condition property to the ClCompile item for the particular source file in the project file, and have it only included in the build when certain properties are set. I think that conditional compilation within the source file is a better option, though, unless you have complex rules that you need to use to determine whether to include a file or not.
In your solution, you can set project dependencies to ensure that one project is built before another. Right-click the solution, select Properties, and browse to Common Properties -> Project Dependencies. Dependencies can also be specified in a project file.
You can execute the output of a build by using a post-build task. Right-click the project, select Properties, and browse to Configuration Properties -> Build Events. The Post-Build event can be used to execute a command when the build has completed.
Rather than renaming an executable after build, it's easier to just have the build produce an executable with the right name. In the Project properties, under Configuration Properties -> General, the Target Name property can be used to set the name of the primary build output.

How to include a build timestamp in a VC++ project?

I am converting a makefile project into a Visual Studio VC++ project. It's actually C source code.
One of the statements I have in my makefile is:
echo char * gLibraryBuildSig ="%DATE% %TIME%"; > BuildTimestamp.c
This produces a C source file with a single line in it:
char * gLibraryBuildSig ="Sun 08/23/2009 17:56:05.05";
In the makefile I then compile all the C source with cl.exe, and after linking, delete the BuildTimestamp.c file. This gives me a global symbol that provides the bubild time as a string.
How can I do the same thing in a VS2008 project? Keep in mind it's not MSBuild.
I'm part-way there. To generate a C module at build time in Visual Studio, I just use the pre-build event.
How do I include that generated file into the compile, but also exclude it from source control and project management?
Or, is there a better way to do what I want?
The compiler (cl.exe) has predefined macros __DATE__ and __TIME__, as well as __TIMESTAMP__. You can compile a file containing only these as a pre-link step.
I might be 10 years late, but I like this simple approach. My solution is
my pre-build step:
echo #define DBJ_BUILD_TIMESTAMP __DATE__ " " __TIME__ > build_time_stamp.inc
That little inc, contains a compile time constant in both C and C++. I usually include it in my main.cpp
#include "build_time_stamp.inc"
Since it is generated on each build, it provokes (re)compilation of main.cpp
Usage might be
printf( "\nBuild time stamp: " DBJ_BUILD_TIMESTAMP );
If you do not what to be bothered by GIT to commit/sync/push, that inc file, after each build, simply do not include it in a project. In any case if you want to use it in some more complex scenario, simply keep it in a global constant:
constexpr auto build_time_stamp = DBJ_BUILD_TIMESTAMP ;
Enjoy ...
Another alternative is to use the preprocessor to include the generated file:
#include "BuildTimeStamp.c"
The file that includes this file can be one of the files in the project under source control.

Resources