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.
Related
Is there a #define/#pragma or something I can add at the beginning of a .cpp file to exclude it from compilation in visual studio? I want to use that for debugging purposes.
You can open the file properties in VS and set Exclude from build to yes under Configuration properties / General.
I don't know of one using #define or #pragma, but you can always do #if 0 at the start of the file and #endif at the end.
I would like to generate a module definition file based on all symbols available in object files in dynamic fashion (think of GTKMM's gendef).
For this, I would like to add_custom_command for PRE_LINK step of a target. However, it looks like there is no easy way to get path to all object files with CMake that would work for plain makefiles as well as for multi-configuration generators like Visual Studio.
Right now, I have the following
add_custom_command(TARGET tgt PRE_LINK
COMMAND gendef ${CMAKE_CURRENT_BINARY_DIR}/tgt.def $<TARGET_FILE_NAME:tgt> ${CMAKE_CURRENT_BINARY_DIR}/$<$<BOOL:${CMAKE_BUILD_TYPE}>:${CMAKE_FILES_DIRECTORY}>/tgt.dir/${CMAKE_CFG_INTDIR}/*.obj
)
However this is quite awkward and bulky as I have to use generator expression in my opinion. Is there a better way to achieve this effect, i.e. call a certain external program for each build configuration?
Is it a CMake bug (feature?) that for plain makefiles, all object files go to CMakeFiles/tgt.dir folder while for multiconfiguration generators all goes to a sibling of CMakeFiles, i.e. tgt.dir/$<CONFIG>? Did I miss some simple variable that would point me to the right place directly?
Turning my comment into an answer
Makefile projects generated by CMake have a totally different internal structure then solutions/projects generated for Visual Studio. I think this is neither a bug nor a feature, those structures are just optimized for their usecases.
And as far as I know there is no easy CMake internal way to get the list of object files or the path to the intermediate files directory with e.g. reading a target property.
So I have taken your code example and have done some testing for alternatives with CMake 3.3.2 using Visual Studio 14 2015 and NMake Makefiles generators.
Alternatives
One related discussion on the CMake mailing list named "CMake: Is there an elegant way to get list of object files participating into a library?" does suggest using an intermediate static library:
add_library(tgtlib STATIC tgt.c)
add_custom_command(
OUTPUT tgt.def
COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> $<TARGET_FILE:tgtLib>
)
file(WRITE dummy.c "")
add_library(tgt SHARED dummy.c tgt.def)
target_link_libraries(tgt tgtlib)
You could add build environment specific elements to your PRE_LINK step:
if(CMAKE_CONFIGURATION_TYPES)
set(_obj_files "$(IntermediateOutputPath)*.obj")
else()
set(_obj_files "$?")
endif()
add_custom_command(
TARGET MainProject
PRE_LINK
COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> ${_obj_files}
)
References
NMAKE: Filename Macros
I have finished a project developed in Visual Studio 2013 (Windows) using OpenCV. Now, my manager told me he needs the code files and the CMAKE file.
I'm reading this documents:
https://cognitivewaves.wordpress.com/cmake-and-visual-studio/
http://www.cmake.org/cmake-tutorial/
but I don't understand properly and I don't know if they are what I need...
I can explain a little bit more my project:
My project has:
main.cpp
Some .cpp created by myshelf.
Some .h created by myshelf.
I use OpenCV libraries (lib, dll, ...)
I use Vimba libraries (lib, dll, ...).
I have never worked with CMAKE files... Could anyone lead me about how create this file/s?? I'm really missed...
THANKS in advance!!!
Any help is welcome!
I have achieve create the makeFile. It's working properly in Windows. I execute cmake and from the code files it create the visual studio project properly and it works fine.
BUT when I try to execute the make command in LINUX I get errors :S:
*In function ..... error: 'infinity' des not name a type const auto....
*.... error: 'infinity' was not declared in this scope
*.... error: 'infinity' was not declared in this scope
*.... error: 'infinity' was not declared in this scope
The line where is the problem is this one:
const auto infinity = std::numeric_limits<int>::infinity();
It's a line from this project: https://github.com/soimy/munkres-opencv/tree/master/src
I think the problem is defining a infinity limit... Could anyone lead me to solve this problem?
THANKS!!!
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.
I have a project where the source files are in source/ and some shader files in data/ (those are not compiled, but instead loaded by the code). I'd like these files to show up in my CMake-generated VS2010 project files so I can edit them comfortably. What's a good way to do this? Ideally, they'd be in a separate project, but anything that works is good.
Thanks!
I can't comment (reputation too low) but is this what you want ?
http://www.cmake.org/pipermail/cmake/2006-May/009291.html
EDIT: if the above link stops working at some time, the idea is to add the files to Visual Studio like an ordinary source file. Since the IDE has no compile tool associated with it, it will be ignored. Quoting the list's discussion:
You could add arbitrary files to a target - as long as VS has no
"automatic" rule to compile them (e.g. .cc, .cpp etc)
I am adding .html files to libraries/executable or using a dummy target e.g:
ADD_EXECUTABLE(dummy dummy.cpp
"${CMAKE_CURRENT_BINARY_DIR}/Doc/index.html")
SOURCE_GROUP command may be useful, too.
and also
I think you have to take care that they are added only to VS IDE
generator builds,
in particular NOT to makefiles.
Thus we are using something like this:
IF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
ADD_EXECUTABLE( hello ${SOURCES} ${HEADER} ${DOC})
ELSE (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
ADD_EXECUTABLE( hello ${SOURCES} )
ENDIF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
Credit to Jan Woetzel