I'm developing application for GNU/Linux using gcc 4 and cmake to manage compilation process. I found that is has no problems when there are two files with the same name but in other directory and namespace like this:
.
|-- gfx
| |-- Object.cpp
| `-- Object.h
`-- logic
|-- Object.cpp
`-- Object.h
First Object class is in Gfx namespace and second in Logic namespace.
Then I've tried to compile this project using Visual C++ 2008 Express Edition. Linker threw several errors about non-existing implementation of Gfx::Object class. After few checks I found out that:
Visual C++ is tracking two of Object.cpp files
When change occurs in first or second file the recompilation of Object unit is queued
It always recompile only the second Object.cpp regardless of which file was actually modified
I also found out that Visual C++ don't allow to create two classes with same name.
Is there a solution for this? I don't really want to refactor quite big part of code.
Both Object.cpp files will be compiled to Object.obj. Into the same directory. In other words, the last one that is compiled will overwrite the Object.obj of the first one. Yes, the linker isn't going to be thrilled by that, you'll get multiply defined symbols since it links the same Object.obj file twice.
The fix is easy, right-click one of the Object.cpp files, Properties, C/C++, Output Files. Change the Object File Name from $(IntDir)\ to, say, $(IntDir)\$(InputName)2.obj
The problem is that by default VC++2008 places all the object files into a single output folder, so the existence of the first object.obj file satisfies the dependency for the second so it is not compiled; and even if it were, it would overwrite the first one.
What you need to be able to do is make the intermediate directory setting dependent in the file being compiled. However I have tried setting it to $(InputDir) and various other combinations, but could not succeed in achieving a configuration that works, although it may be possible. The available macros are documented here.
Failing that you could use a "makefile" project, and manage the build with make, nmake, or cmake or whatever, since there is nothing fundamentally wrong with what you are doing (even if it is ill-advised), it is just that it is not easily supported by the IDE.
This has already been answered, but I also want to add Visual Studio 2010 will automatically put the two .obj files into different directories if there is a conflict, based on my experience with Beta 2.
EDIT: Uh oh, this is wrong! The real answer is that CMake was automatically doing this for me.
The accepted solution is not optimal because it does not scale.
In Visual Studio 2010, I set
Properties -> C/C++ -> Output Files -> Output File Name
to
V:\%(Directory)$(PlatformName)_$(ConfigurationName)_%(Filename).obj
for OBJ files to end up next to the sources assuming the project lies on drive V (no idea whether there is a macro for it, yet).
Not optimal, either - but at least I can easily fork subsystems of many source files without getting tenosynovitis.
By the way: $(InputDir) refers to the solution/project directory and will cause the same problem in another directory.
Related
I've defined a CMakeLists.txt file for my project which works correctly.
I use the CMake GUI for generating a Visual Studio Project, and I ask to build the binaries (CMAke cache and other stuff) in the folder Build which is in the same folder where CMakeLists.txt is.
I was able to specify where the executable and the libraries have to be created.
Is there a way to specify also where the Visual Studio Solution file has to be created? I would like to have it in the root directory, but at the same time I don't want to have also all the other files that CMake creates in the Build directory.
CMake creates the Project I defined in CMakeLists.txt but also two other projects: ALL_BUILD and ZERO_CHECK. What's their utility?
I was able to avoid the creation of ZERO_CHECK by using the command set_property(GLOBAL PROPERTY USE_FOLDERS On).
Is there a way for avoiding also the creation of ALL_BUILD?
It seems you only switched to CMake very recently, as exactly those questions also popped into my head when I first started using CMake. Let's address them in the order you posted them:
I use the CMake GUI for generating a Visual Studio Project, and I ask
to build the binaries (CMAke cache and other stuff) in the folder
Build which is in the same folder where CMakeLists.txt is.
Don't. Always do an out-of-source build with CMake. I know, it feels weird when you do it the first time, but trust me: Once you get used to it, you'll never want to go back.
Besides the fact that using source control becomes so much more convenient when code and build files are properly separated, this also allows to build separate distinct build configurations from the same source tree at the same time.
Is there a way to specify also where the Visual Studio Solution file has to be created?
You really shouldn't care.
I see why you do feel that you need full control over how the solution and project files get created, but you really don't. Simply specify the target for the solution as the origin of your out-of-source build and forget about all the other files that are generated. You don't need to worry, and you don't want to worry - this is exactly the kind of stuff that CMake is supposed to take care of for you.
Ask yourself: What would you gain if you could handpick the location of every project file? Nothing, because chances are, you will never touch them anyways. CMake is your sole master now...
CMake creates the Project I defined in CMakeLists.txt but also two
other projects: ALL_BUILD and ZERO_CHECK. What's their utility? I was
able to avoid the creation of ZERO_CHECK by using the command
set_property(GLOBAL PROPERTY USE_FOLDERS On). Is there a way for
avoiding also the creation of ALL_BUILD?
Again, you really shouldn't care. CMake defines a couple of dummy projects which are very useful for certain internal voodoo that you don't want to worry about. They look weird at first, but you'll get used to their sight faster than you think. Just don't try to throw them out, as it won't work properly.
If their sight really annoys you that much, consider moving them to a folder inside the solution so that you don't have to look at them all the time.
Bottom line: CMake feels different than a handcrafted VS solution in a couple of ways. This takes some getting used to, but is ultimately a much less painful experience than one might fear.
You don't always have a choice about what your environment requires. Visual Studio's GitHub integration requires that the solution file exists in source control and is at the root of the source tree. It's a documented limitation.
The best I was able to come up with is adding this bit to CMakeList.txt:
# The solution file isn't generated until after this script finishes,
# which means that:
# - it might not exist (if this is the first run)
# - you need to run cmake twice to ensure any new solution was copied
set(sln_binpath ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.sln)
if(EXISTS ${sln_binpath})
# Load solution file from bin-dir and change the relative references to
# project files so that the in memory copy is as if it had been built in
# the source dir.
file(RELATIVE_PATH prefix
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
file(READ ${sln_binpath} sln_content)
string(REGEX REPLACE
"\"([^\"]+).vcxproj\""
"\"${prefix}/\\1.vcxproj\""
sln_content
"${sln_content}")
# Compare the updated contents with the existing source path sln, if it
# exists and is the same we don't want to disturb VS by touching it.
set(sln_srcpath ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.sln)
set(old_content "")
if(EXISTS ${sln_srcpath})
file(READ ${sln_srcpath} old_content)
endif()
if(NOT old_content STREQUAL sln_content)
file(WRITE ${sln_srcpath} ${sln_content})
endif()
endif()
What would be helpful is if cmake had a way to run post generation scripts, but I couldn't find one.
Other ideas that didn't work out:
wrap cmake inside a script that does the same thing, but:
telling users to run a seperate script isn't simpler than saying to run cmake twice. Especially since needing to run cmake twice isn't a foreign concept.
put it in a pre-build step, but
building is common and changing the build is rare
changing the solution from builds inside the IDE makes it do... things
use add_subdirectory because that's suppose to finish first
it appeared to make the vcxproj's immediately, but not the sln until later, but I didn't try as hard because this adds a bunch of additional clutter I didn't want - so maybe this can be made to work
Error 2 error LNK1104: cannot open file 'OgreMain_d.lib' C:\Users\Owner\Documents\Code\C++\Test\ogrevcpp\ogrevcpp\LINK ogrevcpp
This is the error I get when trying to build an Ogre3D application (with steps followed from here).
I've followed everything to the T, yet I still get the error. It honestly shouldn't be happening. I've also followed everything from here.
Edit
What's happening is there are two different files, one is meant for release, the other is meant for debug. I need the one for debug mode to compile properly (which is OgreMain_d.lib).
Update
I figured out what the problem was - I was using the incorrect binaries; there was a few releases which were meant for Visual C++, and one which was meant for MinGW, along with a few other compilers. My apologies.
You need to check your library paths to make sure that the path where OgreMain_d.lib lives is part of the library path.
I guess the library for Debug mode is not present in the lib folder. Try putting two different libraries folder for each Assembly mode in Visual Studio. Go to ProjectProperties -> Configuration Properties -> Linker -> Additional Library Directories on Right hand. Make sure to check the Configuration Dropdown on the top.
I come from a Java background, and the shop where I currently work refuses to use anything other than MS VC++ to build their legacy project. They don't appear to use any standards for setting up their build environment other than just building it using VS2005 and clicking the compile button.
I was wondering if there was anything closer to what Java had for instance:
A build tool like ANT or Maven
A directory structure that makes sense containing
src - Place for all my source files .c/.cpp/.h
lib - A place for any libraries that might be used in the project (.dll, .lib)
dist - A place for the output executable/distribution of the project
resources - A place for any images/sounds/text files that might be included in the project.
build.xml - Some sort of a build file (my guess would be something like ./configure or MAKEFILE)
Or am I asking too much from a C++ build environment? Is it just always as chaotic as the people in my shop make it out to be? I really have a hard time believing that considering the success of so many C++ projects on the internet.
It sounds like you have good intentions - coming form a non MSVC world I can see your points.
If I were in y our shoes I would definitely make a command line/automated build/build server.
You can use MSBuild for this - and hudson has a plugin for this. I usually have a "Build" directory near the root of the projects that contains scripts/etc that will call the appropriate MSBuild/.sln files.
The "makefiles" for Visual Studio are .sln and .vcproj files. You can call those with msbuild from the command line. You can also export a makefile (I think that is still an option) from within the IDE that you can run. I don;t recommend going that route though other than trying it out and seeing what is output - since that is what you are familiar with.
Both the vcproj and sln files are human readable - go through them - it will give you some useful information.
I would also agree that having a distributon directory is good - for building an installer/etc after the build. Copy all the needed binaries there - either in postbuild steps or in another script/etc.
Let us know what you end up doing.
I have one other piece of advice:
UPGRADE to VC/Dev studio 2008 or 2010. ASAP
MSVC does not impose any directory structure on you. There are some defaults, as mentioned above for the Debug and Release directories, for example, but even these can be overridden on a per-project basis. Use whatever directory structure makes sense to you.
Visual Studio does provide command line support if you don't want to use the IDE. See This MSDN Article for more information.
You can setup a proper build environment using Visual Studio (and for solutions with more than one project, you should), and there are a number of environment variables to use in the project configuration to set so that output files and intermediate files go to different folders than those defined by default.
In our large VS solution, we use e.g. obj/$(ProjectName)/$(ConfigurationName) as intermediate directory and bin/$(ConfigurationName) as output directory in all sub-projects.
All these things must be enforced by the user, and it seems that no single recommendation/best practice has evolved.
The standardized stuff:
The build tool: Visual Studio (doesn't need an extra product)
Build file: *.sln / *.vcproj (*.vbproj for Visual Basic, etc)
Directory structure: "Debug" and "Release" directories for the output binaries.
The rest isn't so much "chaotic" as "doesn't really matter". "Chaotic" suggests that it changes all the time, but in reality you just pick one for a project and stick with it. Companies may have internal standards across projects. It just doesn't matter enough to bother standardizing across companies. C++ is a complex language anyway; anyone with sufficient IQ to read C++ can deal with reasonable variation. The difference between \lib\ and \Library\ won't stop them.
(I'm new to CMake and I am not so familiar with Visual Studio.)
I need to implement a relatively big library the solution/project files will be generated by CMake, and my problem is that I would like the organization of the files in VC GUI to reflect the directory structure on the disk.
Basically, the library is split into different parts. For instance one of them is called "common" and will implement some headers used by the library. On the disk it will be in a specific "common" directory, which may have one or more subdirectory.
src/
common/
...
portfolio/
...
asset/
contracts/
physical_assets/
...
mathutils/
...
I'd like to have the see the same thing within Visual Studio's Solution Explorer,
but I only know how to split the solution into different projects.
How can I do that?
You can do that using SOURCE_GROUP, the CMake FAQ covers that.
I don't think you can. If you use "Show All Files" you will get what you want, but only at the project level. Creating a VS project at the root may give you the possiblity of viewing all your files, but you will still need separate projects for each exe/dll/etc. you want to build. Remember that a solution in VS terms is a set of projects, not a directory tree.
Not sure if this is what you're after, but: first make sure you have "Tools->Options->Projects and Solutions->Solution Explorer Mode" set to "Show All Files". Then if you create a VS project in the root source directory (probably the same as where your CMakeLists.txt goes), VS will show all files in that directory and all it's subirectories.
I've got a really large project I made for myself and rece3ntly a client asked for their own version of it with some modifications. The project name was rather silly and my client wants the source so I figured it'd be best if I renamed all my files from
sillyname.h
sillyname.cpp
sillyname.dsp
etc..
Unfortunatly after I added everything back together I can't see any way to change the project name itself. Plus now I'm getting this error on compilation.
main.obj : error LNK2001: unresolved external symbol __imp__InitCommonControls#0
Debug/New_Name_Thats_not_so_silly.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
There has to be an easier way to change all this, right?
Here is a Step by Step on Steve Andrews' blog (he works on Visual Studio at Microsoft)
I haven't verified this, but I've done this a number of times and if my memory serves me right, you can actually use the search-and-replace functionality in VS2005 to rename all instances of the string "X" to "Y" in any type of file.
Then you need to close the solution and change the project (and any other file with the same name regardless of extension) file name(s).
You will obviously need to do a full rebuild afterwards.
I find it always annoying too, to do this manually.
So I tried some tools available by googling- two didn't work (VS C++ here), dunno, if they are more useful for C#.
The following tool worked good for me: I have used the trial version, but I will pay 39,- bucks for it. For me it is worth it. It has also a VS add-in. VS 2013 was not supported directly, at least not mentioned, yet, when I looked:
http://www.kinook.com/CopyWiz
In-place rename didn't work (access error), but "rename-while-copying" worked fine.
But I really wonder, if it is so difficult as some programmers claim. For most parts file renaming and a search&replace of all occurences in all text files in the project dir should be a quite easy and working approach. Maybe someone can contibute what shall be so difficult.
The rational part of my brain forbids the dreaming part to program an own tool- I am lucky ! :-)
You can simply rename the .vcproj or .dsp file and then either create a new workspace (sln dsw) and include the renamed project or simply chnage the name inside the sln file (it's just xml) I can't remember the format of the old workspace but it's still text.
You can either manually rename and reinclude all the .cpp of edit the project file and rename them in there.
sorry don't know of refactoring tool that will do all this but there probably is one.
I assume that in addition to the renamed set of files, you also still maintain a complete "parallel" set of the original files in some other directory, am I right?
Assuming you have both versions, what I would do is:
Get a file comparison tool like Beyond Compare or DiffMerge and compare the old SLN file and the new SLN file side-by-side. Also do this for each "proj" file and any other "config" type files.
It is possible to edit these files by hand. Usually looking at what is different between two copies will help illuminate what you should do to get the second one working.
You might as well start tinkering with the renamed project by hand, anyway, given that it already isn't working. You can't make it much worse. And: you might learn some handy tricks about the XML structure of these files.
Even if you do make small mistakes when hand-tweaking this files, I have repeatedly been very impressed by how Visual Studio handles things. Visual Studio will usually tell you exactly where you got it wrong.