How to compile/use header units in MSVC from command-line? - c++

For example I have following toy files:
mod.hpp
#include <iostream>
use.cpp
import "mod.hpp";
int main() {
std::cout << "Hello, World!" << std::endl;
}
But if you compile it like cl use.cpp /std:c++latest then I get error
error C7612: could not find header unit for 'mod.hpp'
How do I create/use header units in MSVC?
NOTE: I'm making cross-platform/cross-compiler projects right now. It means that I want same sources to be able to compile in MSVC/CLang/GCC on both Windows and Linux. For me there is no point to make MSVC-specific extensions .ixx/.cppm, thats why I used .hpp/.cpp in my case. More then that I'm not making .vcxproj/.sln files at all, I'm only considered about low-level command line invocation for compiling in MSVC.
This question was made by me just to share my answer with ready-made solution.

To create precompiled header unit issue next command:
cl /EHsc /std:c++latest /exportHeader mod.hpp
this command creates mod.hpp.ifc file, which is a precompiled header unit module. Here is documentation about /exportHeader flag.
Then to use header unit issue command:
cl /EHsc /std:c++latest use.cpp /headerUnit mod.hpp=mod.hpp.ifc
documentation about /headerUnit is here. /headerUnit accepts param header-filename=ifc-filename. After command above final program compiles and outputs:
Hello, World!
This way you can precompile any header, including standard ones like import <iostream>;.
For commands above I used following files:
mod.hpp
#include <iostream>
use.cpp
import "mod.hpp";
int main() {
std::cout << "Hello, World!" << std::endl;
}

Related

MinGW G++ not compiling

I'm trying to compile a simple "hello world" C++ program but when I use the g++ command I get the error "undefined reference to `WinMain#16" this happens when I compile in vscode or in terminal, whats happening?
code:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> msg {"Hello World"};
for (const string& word : msg)
{
cout << word << " ";
}
cout << endl;
}
Your error is not a compiler, but a linker error.
That means it still compiles fine but fails to link.
A header file gets included (if it can be found in the include path the compiler uses to find headers), so this works fine.
But for linking two (object-)files together it has to know which files should be linked. And how should it decide which files to use?
That's the cause to create projects in it (and other IDE's) or to create makefiles.
If you turn on full command line-logging in "Settings -> Compiler and debugger... -> Global compiler settings -> [the_compiler_you_use] -> Other settings (rightmost tab) -> Compiler loggin" you can see which commands are sent to the compiler/linker and where the difference is between a single file and a project with multiple files.
By the way: your book/tutorial should explain the steps needed to compile and link files, what happens if headers are included and how to use prebuild libraries/dlls.

"undefined reference to `WinMain#16'" Error in gcc editor

I am just learning c++ and began to watch a youtube tutorial by thenewboston. Unfortunately he is using Code::Blocks while I am using gcc and I do not have the option to create new class files with a button click and so had to manually create them.
I dont understand why the same code in Code::Blocks and gcc will work in Code::Blocks but not gcc. Does gcc require different coding for the same language?
EDIT: I have downloaded and tested in Code::Blocks myself
Other questions talk of how I need to give windows an entry point, but I dont know how to do that.
Test.cpp Code:
#include <iostream>
#include "ClassTest.h"
using namespace std;
int main() {
ClassTest bo;
}
ClassTest.h Code:
#ifndef CLASSTEST_H
#define CLASSTEST_H
class ClassTest {
public:
ClassTest();
};
#endif // CLASSTEST_H
ClassTest.cpp Code:
#include <iostream>
#include "ClassTest.h"
using namespace std;
ClassTest::ClassTest() {
cout << "blah blah" << endl;
}
I'm not quite sure I understand what the question is; I'm going to take it as "how do I get these three files to build into a .exe that I can run from the Windows commmand line?"
The answer is to run something like this on the command line, in the folder with the files:
g++ -c Test.cpp -o Test.o
g++ -c ClassTest.cpp -o ClassTest.o
g++ Test.o ClassTest.o -o Test.exe
The first two commands build each CPP file into an "object file", which isn't a whole program by itself but which contains the compiled version of the code in that CPP file. The last command tells the compiler to paste together the two object files into a program, and resolve all the cross-references between them. (For example, the part where Test.cpp constructs a ClassTest object needs to end up calling the ClassTest constructor code from ClassTest.cpp.)
Code::Blocks is an IDE and works out how to build each source file in your project and link them together by itself. But if you aren't using an IDE, you need to do that in another way. You can either do it manually like this, or you can write a Makefile that will check which code files have changed and rebuild and re-link everything that depends on them when you run the make command, which is how most people do it.
As for "giving Windows an entry point", that probably refers to GUI applications that want to display windows on the screen. For console programs like the one you have written, the "entry point" is main(), and you just print stuff to the command line window. To make actual Windows-style GUI windows of your own, you need to use the Windows API, which I can't tell you much about.

C++ run project as standalone files, rather than a Code::Blocks project

Good afternoon!
I'm currently working on a final project to close my first semester of C++ (and also programming in general) and I was wondering how I can properly link the implementation, header, and main files. The purpose is to be able to run them as just those 3 files, instead of being dependent on running them through a .project file.
This is an example of the project I'm doing:
Cat.cpp
#include <iostream>
#include "Cat.h"
using namespace std;
void speak()
{
cout << "meow" << endl;
}
void jump()
{
cout << "meow?" << endl;
}
Cat.h
#ifndef CAT_H
#define CAT_H
void speak();
void jump();
#endif // CAT_H
CatMain.cpp
#include <iostream>
#include "Cat.h"
using namespace std;
int main()
{
speak();
jump();
return 0;
}
The issue here is that when I open these files individually (without opening the .project file), I get the "undefined reference to WinMain#16" on Cat.cpp and "undefined reference" errors to the speak() and jump() functions on CatMain.cpp. The reason this might be an issue is because chances are that my professor won't have Code::Blocks to run it the same way as I do, so he will have to be able to run these standalone files rather than run the .project file.
Is there something I can do to link them together so that they're not dependent on the .project file to run properly?
Any help would be greatly appreciated =)
To run this or any C++ program without an IDE, you only need a C++ compiler available on the command line. (You may have to set an environment variable to the path to the compiler to use it on the command line)
To compile and run the code one could run the following commands on the command-line. (assuming a compiler such as GCC or MinGW, which uses the command g++ to compile C++)
g++ -c Cat.cpp (produces an .o object file for the implementation of Cat.cpp and Cat.h)
g++ CatMain.cpp Cat.o (compiles the main function as an executable and links the Cat.o to it)
a (in windows cmd)
./a.out (on *nix systems)

Compile C++ with static lib

this will probably a dumb question for you guy's but I have no experience in C++ what so ever. I'm using an open source project osrm (which is awesome). Still to request a route, you have make an http request. To reduce the running time, I would like to build a wrapper around the code and call it using the command line. So I googled a bit and found that osrm already creates a static lib (.a file) when compiling the project. I also found a piece of code that points me in the right directions for building a wrapper. So to begin I build a simple hello world program (see below) that includes some files from that static lib. To compile I followed this tutorial.
My directory structure looks like this:
./helloWorld.cpp
./libs/libOSRM.a
And the command to compile is this:
gcc –static helloworld.cpp –L ./libs –l libOSRM.a
The code it selve:
#include "Router.h"
#include "boost/filesystem/path.hpp"
#include "ServerPaths.h"
#include "ProgramOptions.h"
#include <InternalDataFacade.h>
#include <viaroute.hpp>
#include <iostream.h>
main()
{
cout << "Hello World!";
return 0;
}
the exact error I got:
fatal error: ServerPaths.h: No such file or directory #include "ServerPaths.h"
Add the -IPathToTheHeaderFiles to the compiler options. So it will find the files to be included. Replace PathToTheHeaderFiles with the path where your file ServPaths.h resides.
Edit: Add as many -I as you need for further header files.
Additionally it would be worth to read a book about C++ or/and the GCC manual1
1 Section 3.11 will help.

Compiling simple Hello World program on OS X via command line

I've got a simple hello world example that I'm trying to compile on OS X, named hw.cpp:
#include <iostream>
#include <string>
using namespace std;
int main() {
cout << "Hello world!" << endl;
return 0;
}
I'd like to compile it using gcc, but I've had no success. I'd also like to hear the other options, like using Xcode ?
Try
g++ hw.cpp
./a.out
g++ is the C++ compiler frontend to GCC.
gcc is the C compiler frontend to GCC.
Yes, Xcode is definitely an option. It is a GUI IDE that is built on-top of GCC.
Though I prefer a slightly more verbose approach:
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
}
g++ hw.cpp -o hw
./hw
user#host> g++ hw.cpp
user#host> ./a.out
Compiling it with gcc requires you to pass a number of command line options. Compile it with g++ instead.
Also, you can use an IDE like CLion (JetBrains) or a text editor like Atom, with the gpp-compiler plugin, works like a charm (F5 to compile & execute).
The new version of this should read like so:
xcrun g++ hw.cpp
./a.out
Use the following for multiple .cpp files
g++ *.cpp
./a.out
You didn't specify what the error you're seeing is.
Is the problem that gcc is giving you an error, or that you can't run gcc at all?
If it's the latter, the most likely explanation is that you didn't check "UNIX Development Support" when you installed the development tools, so the command-line executables aren't installed in your path. Re-install the development tools, and make sure to click "customize" and check that box.