Is there a Standard(ish) or a way todo this is Visual Studio to dealing with different source files for different compile options?
Right now I have an OpenGL and DirectX framework and I am in the process of merging them together. Currently how I'm differentating them is by included in a #if defined in the source file
// GraphicsGL.hpp
#include <platform.hpp>
#if defined(USE_GL)
// code
#endif
and
// GraphicsDX.cpp
#include <platform.hpp>
#if defined(USE_DX)
// code
#endif
I don't want to go down the path of two different projects, there is more stuff that isn't dependent on platform than is.
You can exclude files from build and you can specify preprocessor symbols definition per file; just right click the file then properties in the solution explorer
I would recommend that you factor out the platform dependent code into its own library and you build different versions of it. The actual project would have separate build configurations that would use one or the other.
Related
I am writing my own C++ project library in visual studio (couple of projects that consist of *cpp, *.h files, NOT an actual .lib file). Each of these projects is located in single Visual Studio "solution".
When I needed to use a code from one project in another, I just copied it. But that was short term solution. Now my library has grown both in size and functionality, and because of code duplication I ended up with dozens of different versions of the same file.
That single solution serve me as a playground // test ground for new ideas. I am developing projects not libs. Currently it holds about 50 projects.
I am working on visual studio 2015.
Lets say I have setup like this:
DataIO project located in */Solution/#DataInputAndOutput/DataIO/DataIO.h
consist both of DataIO.h and DataIO.cpp
Foo project located in */Solution/#Foo/Foo/Foo.h
consist both of Foo.h and Foo.cpp
DataIO.h:
#pragma once
#ifndef __DATA_IO_H__
#define __DATA_IO_H__
// ...
extern FILE * const logFile;
// Bunch of function declarations
#endif // !__DATA_IO_H__
I know that this is not a "Minimal, Complete, and Verifiable example" but my problem lies in logistic of things, not things themselves. And I believe that my description is sufficient.
Problem #1: In Foo.cpp I #include "DataIO.h" (with is possible because i added additional include directories in Foo project setup) But whenever I try to compile Foo I am given following error: unresolved external symbol for every function declaration inside DataIO.h and that one external variable. How Can I Fix this problem? Do I need to create a DataIO.lib to keep things straight?
I tried to add DataIO.h and DataIO.cpp into Foo project directly (NOT copy it, just add it into project) but that seems like a bad idea...
I recommend trying out the new "Shared Items Project" in VS2015+. A Shared Items Project is literally just a set of files. The project itself doesn't build anything. In fact, there are no (or almost no) compilation or linkage settings in a Shared Items Project -- those settings come the the project that references the Shared Items Project. When you reference a Shared Items Project from some other project FOO, the build of FOO happens as if the files of the Shared Items Project are items of the referencing project.
Short of that, you can set up your shared projects to build .libs and then use Project References within Visual Studio to automatically set up the linkage. I think you have to manually set up the include paths when doing this, though.
The best way to do this is to factor out common code into a library so the common code resides in one place. And then have your projects use the library - via an include file and linking with said library.
Why does the compiled and linked executable file contain paths of header files included in my source code? I am using the wxWidgets library and compile with Visual Studio 2013 and gcc. What are these header files used for? If it is a compiler option, how can I disable it to avoid this?
Build configuration: release, static linking.
There may be several explanations for such strings to appear in the executable file:
You may have debugging information bundled in the executable for the debugger to use. Use strip to remove that, or do not use the -g compile option. You should also compile with NDEBUG defined to disable debugging code and assertions. It is usually the case for the Release mode, but you may want to double check.
Some functions may use __FILE__ for tracing or logging purposes. __FILE__ expands to the source file name at the point of macro expansion, which may be a source or a header file. One such function is assert(): it is actually a macro that expands to a test and some error reporting code that includes the current filename.
Some sources may have static source ids in the form of static char arrays to keep track of source code versions. This approach is quite obsolete, but many old sources still have them.
Look for such things in the source files or header files whose name appear in the executable and fix the problems.
wxwidgets has many asserts in its header files (e.g. in wx/string.h as you noticed), all using the wxASSERT macro defined in wx/debug.h
In order to disable these, you can #define wxDEBUG_LEVEL 0 prior to including any wxwidget headers.
One source with multiple objects
I am using MSVS 2010 and I have a C++ source-file which must compile into 2 object-files.
The diiference between those compilations is a "#define UNICODE" for one of them but not for the other.
I can't (and don't want to) use templates for a this.
Currently ,I use 3 source files for this in my project.
The actual source is excluded from build ,while the other 2 are wrappers around it.
Like this :
file = wrap-UNICODE.cpp
#ifndef UNICODE
#define UNICODE
#endif
#include "actual-source.cpp"
// eof
file = wrap-ANSI.cpp
#ifdef UNICODE
#undef UNICODE
#endif
#include "actual-source.cpp"
// eof
When using makefiles i can easily avoid the use of wrapper soucrces ,using different output
switches.
My question is ,I would like to know if (and how) i can do this directly in a MSVS project.
If i correctly understand what you want to do, this is possible.
I have MS Visual Studio 2005 Standard Edition; here is how i can do this (you might have to adjust this if you have a different version, or possibly it might even not work in your version; i hope your computer doesn't explode :) ).
The first step requires manual editing of the project file. Open the project file (it is called stuff.vcproj on my machine) and replicate the lines that mention your file:
<File
RelativePath=".\actual-source.cpp"
>
</File>
<File
RelativePath=".\actual-source.cpp"
>
</File>
Then, load the project into MSVS. Go to the Solution Explorer (Ctrl+Alt+L on my machine); the project will show two files with identical name. Open the Property Pages of each one (Alt+F7 on my machine) and add any differences you want (e.g. Preprocessor Definitions).
You must also set different names for object files: choose Output Files, Object File Name in the same window (Property Pages), and add different names (e.g. actual-source-unicode; MSVS will add the .obj extension when compiling). If you don't do that, the two obj-files will have the same name, and one will overwrite the other.
AFAIK you can create multiple builds in your solution. Just go in the configuration manager of the solution (should be accessible from contextual menu on the solution).
In this way you can also avoid to have two versions of your file. It is sufficient to set the define options differently in the two configurations.
Visual Studio defines _UNICODE for you if you intend to build unicode apps.
Why don't you simply use different configurations for your two builds (as Luca Martini mentions) and then use Batch Build? You can then compare the compiled outputs any way you want.
I have some .h files as follows (on Linux)
Source/Server/connect.h
Source/Server/message.h
...
I am developing another application that needs the two .h files but is in a different directory
Source/App2/..
How can I include the connect.h file in the App2 application, considering that I use perforce and everyone else working on the application would have their own copy so adding an absolute path to the include library might not be a good idea but im not sure.
EDIT:
I use a proprietary build mechanism for building the code so will not be able to specify gcc options directly.
You can #include a relative path to the files:
#include "../Server/connect.h"
or you can add a flag to tell the compiler to look in the other directory. For gcc you can use -I../Server; for Visual C++ you can use /I"../Server"; other compilers, I'm sure, have their own flags for this purpose.
I think the second is better in most cases, since it allows you to move your projects around while only requiring you to modify the include path in one place (the makefiles or property sheets).
What about adding include search path to he compiler, for gcc it's -I switch.
I suggest removing paths from the #include statements. As others have stated, put the paths into the parameters to the compiler. Resolve the path differences in the makefile or use environment variables (may need to do both).
My experience is that files will move. Anything that doesn't use relative paths will break the build (which is very bad).
in addition static relative paths, you can also play with preprocessor chicanery. One technique I saw used at Adobe for cross-platform code, was to do something like this:
/* globalplatform.h */
#ifdef MAC
#define PLATFORM "../Platform/Mac/MacPlatform.h"
/* custom standard IO etc */
#define STDIO "../Platform/Mac/io/stdio.h"
#define CTYPE "../Platform/Mac/io/ctype.h"
#endif
#ifdef WIN32
#define PLATFORM "../Platform/Win/WinPlatform.h"
#define STDIO <stdio.h>
#define CTYPE <ctype.h>
#endif
/* etc */
#ifndef PLATFORM
#error undefined PLATFORM
#endif
/* some C file */
#include "globalplatform.h"
#include PLATFORM
#include STDIO
/* don't need CTYPE, no penalty */
While the platform problem isn't your problem, you can define the relative paths based on build configuration if you want to and the config changes happen in one place instead of many and client files only pull in what they need. The down side is that any tools you use for browsing header files (right-click and so on) are hosed.
You can change the compiler directives as above, or modify the path within your code (either relative or absolute).
I would suggest that you consider the best locations for headers and object files (and libraries) for all your projects and set that up.
If you have standard include and lib locations you'll simplify the development down the road
I have a VS generated C++ Win32 DLL project. It has the following files:
stdafx.h
targetver.h
myProject.h
dllmain.cpp
myProject.cpp
stdafx.cpp
I can remove targetver.h, and merge dllmain.cpp into myProject.cpp. What more can I do to get the simplest file structure, preferably one file. I need to dynamically emit this code file and build it into a Win32 DLL.
If you want a minimalistic file structure, you could just create the files yourself. Start an empty project, or delete all the files. Heck, just make a folder, write main.cpp, and compile it from the command line with cl.
Few IDEs really try to minimize files like you're trying to -- but when you create the project, you can cut back a little: stdafx.[h, cpp] are for precompiled headers, which you could disable when creating the project.
That said, I don't really see the value in minimizing the amount of source code in a compiled language project -- it's not going to have a meaningful impact on the number of output files/dlls and, properly used, using more files only helps your code's clarity.
In addition to what Andy said, you can merge the myProject header and implementation files as well with dllmain.cpp. But why not just keep these files and create the vsproj file at runtime?
Or you could just create an empty project.
IIRC, myProject.h and myProject.cpp both contain an example of an exported class. You can easily delete those.
stdafx.cpp and stdafx.h are used for the standard precompiled header file. If you turn off the setting that requires a precompiled header, then those files won't be necessary, either.
You could #include your generated file into a existing multi-file project. That way you can have a shell of a complicated project and only emit something smaller, like a simple function.
For example:
#include <system_stuff>
void main()
{
Go();
}
#include "generated_file_that_has_method_go.cpp"
void other_code()
{
}