C++20 compiling modules with Visual Studio: doesn't compile or import ixx files - c++

Visual Studio 2019 doesn't attempt to compile my .cxx or .ixx files. Here is my .cxx file:
export module greetings;
import std.core;
export std::string get_greeting_text()
{
return "Hello, World!";
}
and here is main:
import std.core;
import greetings;
int main()
{
std::cout << get_greeting_text() << '\n';
}
I do have these flags set: /std:c++latest, /experimental:module. Error messages are
C:\...\main.cpp(2,17):error C2230: could not find module 'greetings'
C:\...\main.cpp(6,2): error C3861: 'get_greeting_text': identifier not found
...but I don't see any line about trying to compile greetings.cxx, so that's got to be the problem. Changing it to .ixx has no effect. What's the fix?

Solution:
Add greeting.ixx to Header Files. (It won't work to add it to Source Files.)
Right-click properties on greeting.ixx, and
Set Item Type to C/C++ Compiler
Set Excluded from Build to No.
Save
Build
It seems a little flaky. Rebuild failed unless I did a Clean first.

Module declaration export module greetings; is not yet working on Visual studio 2019.
You may try to add the following compiler opinions for your greetings.cxx file:
/module:export /module:name greetings /module:wrapper greetings.h /module:output greetings.ifc -c greetings.cxx
Another solution, rename greetings.cxx to greetings.ixx. The .ixx extension is required for module interface files in Visual Studio.

In order to use a different file extension with MSVC so you can use intellisense in Visual Studio Code, there is actually a work-around.
With the cl.exe command, there is an '/interface' option. You can do like so:
In My cl.exe CommandFile:
/interface /Tp UI/ApplicationHost.cpp
/reference ApplicationHost=Build\Debug\ApplicationHost.ifc
UI/WorldEngine.cpp
/link /SUBSYSTEM:WINDOWS
Build/Debug/pch.obj
/Interface - Let's the compiler know there is an ifc module/header coming up.
/Tp - Forces the compiler to recognize it as a C++ file, useful if renaming to .cppm.
/reference - Tells the compiler where to get the dependency information for the following source code.

Related

MASM: A1000 error, unable to open file (assembly)

I have a Visual Studio 2017 project, where I'm trying to interface a C++ and Assembly program. So I have a header ("indexof.h") that has the Prototypes for the assembly procedures in an extern "C" block, and a main.cpp, which includes indexof.h and uses the procedures made available in it, and then an IndexOf.asm file that contains my assembly code (which also has prototypes for its procedures, before the .code section). Unfortunately, when I attempt to run it, I get this error:
1>Assembling IndexOf.asm...
1>MASM : fatal error A1000: cannot open file : IndexOf.asm
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\BuildCustomizations\masm.targets(50,5): error MSB3721: The command "ml.exe /c /nologo /Zf /Zi /Fo"Debug\IndexOf.obj" /W3 /errorReport:prompt /TaIndexOf.asm" exited with code 1.
1>Done building project "IndexOf_asm.vcxproj" -- FAILED.
I desperately need help (It's due tomorrow), this was a project setup provided by my class, I'm just trying to run it, and I haven't even gotten to the actual thing I need to do yet. Thank you!

cl error 0xc000007b when invoked from scons script

I am trying to compile a simple program using scons + MSVC compiler under Windows. Program source is just simple "Hello world".
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!\n";
return 0;
}
SConstruct is utterly simple:
Program("hw.cc")
When I run scons in the source directory, I get
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
cl /Fohw.obj /c hw.cc /TP /nologo
scons: *** [hw.obj] Error 123
scons: building terminated because of errors.
in the console and pop-up message with 0xc000007b error.
Aslo results of where command:
where cl
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\bin\Hostx86\x86\cl.exe
where scons
C:\Python35-32\Scripts\scons.bat
I don't have any clue what's wrong.
UPD
SCons debug output
UPD 2
After some experiments with cl and scons I have finally figured out what was wrong and how to fix it.
First of all, cl should be available from the command line. If after entering command cl in the console you get errors like command not found, you should add path to cl.exe to the PATH system variable. In my case
PATH=<rubbish>;C:\Microsoft\VC\Tools\MSVC\14.14.26428\bin\Hostx86\x86;
After this you should set up variables INCLUDE and LIB to tell compiler and linker where to find include files and libs. And this part is a little bit tricky, because, to my surprise, cl does not compiling anything without Windows Kits 10 (whatever it is). Thus, you should specify its includes and libs accordingly. In my case
INCLUDE=C:\Microsoft\VC\Tools\MSVC\14.14.26428\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt
LIB=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17134.0\ucrt\x86;C:\Microsoft\VC\Tools\MSVC\14.14.26428\lib\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17134.0\um\x86
When these variables are set up correctly, hw.cc should compile fine.
And, probably, this should do the trick for scons too, but to make one hundred percent sure it works correctly, SConstruct should be modified to something like this
import os
env = Environment(ENV = os.environ)
flags = ["/EHsc"] # Flags are completely optional
env.Program("hw.cc", CXXFLAGS=flags)
With all these steps, everything should compile fine.

How to export functions and classes from module not using `export` keyword?

I'm investigating an opportunity of using C++ Modules TS in my pet project. One of the important use cases for me is wrapping of legacy headers.
Suppose I have a header file with some functions and classes, std.io.ixx:
int f(int x)
{
return 2 + x;
}
According to this article, I compile the module using the following command:
cl /c /experimental:module /module:name std.io /module:export std.io.ixx
Which gives me a new file std.io.ifc. Then I use this module in another source file, main.cxx:
import std.io;
int main()
{
f(5);
}
Which is compiled with the following command:
cl /c /experimental:module main.cxx
The compilation gives me a following error:
main.cxx(5): error C3861: 'f': identifier not found
So, as we can see, the identifiers from the module were not exported. I could fix this by manually adding export keyword before each identifier I want to export, but this is impossible for the use case of wrapping the legacy headers.
What I'm doing wrong? How to export all possible identifiers from a header?
I believe there are two things wrong:
The module name must not start with std.. When I attempted to do that, I got the error
error C3674: could not find standard library module 'std.io'
This error might not appear if you haven't installed the Standard Library Modules component for Visual Studio. I'm not sure about this, though.
In the blog post you linked to, there's this note:
Note that you currently have to include your header in a .cpp file (or rename your header) because of a limitation in our compiler’s file handling.
That indeed appears to be the case because when I tried with the extension ixx, I got the same error as you.
But after fixing both of the above issues, it worked fine.

How do you run cl.exe from cmd using the same settings as in MSVS?

I have a c++ project in MSVS 2010 Express. I have been planning to write several unit tests to validate this project. Right now they go along the following lines:
#include "header.h" //Header is the header for the source I want to test
void testSomeFunction()
{
//Call function (from external src, prototype in header.h)
//Save output to file
}
int main()
{
testSomeFunction();
return 0;
}
I am creating these source files outside my project because I want to be able to run each of them as individual executable, but I am having trouble getting the Microsoft linker to link them.
This is my problem so far (CMD output):
cl ut_Converter.cpp Converter.obj
ut_Converter.cpp
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(323) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:ut_Converter.exe
ut_Converter.obj
Converter.obj
Converter.obj : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in ut_Converter.obj
Converter.obj : fatal error LNK1313: pure module detected; cannot link with ijw/native modules
I never really use Microsoft products, I'm familiar with using the GNU tools GCC and make but I have to use the Microsoft tools for this and I have no idea how they work.
Maybe I'm going about building these tests the stupid way but it's the best way I can think of right now.
This is what I want to do:
Compile the source files in my project into object files
Compile my test files into object files
Link the test object file with the appropriate project object files to produce the test executable
How do I go about doing that? (I'm guessing there are some settings I need to set to make everything compatible but I have no idea what they are or how I would go about setting them)
Extra: I know it mentions the debug level but I'd be willing to bet that there will be other incompatible settings. Is there a way to find out what the settings are in the program so I can pass them to cl.exe when I run it?
Edit: When I say command prompt I do mean the one that comes with Visual Studio with all the environment variables setup.
Have you tried going to Programs / Microsoft Visual ... / ... Tools / ... Command Prompt, and running from that dos console window which has the environment variables setup?

MSVS C++, how to compile already-preprocessed file with *.i extension?

Related question here: How can I run the MSVC preprocessor and compiler in two separate steps?
I explicitly pre-process a MyFile.cpp (not compile) to a MyFile.i. I want to later "compile" that file (explicitly skipping preprocessing would be nice, but as the related question suggests, it sounds like that is not possible with MSVS.)
PROBLEM: The MyFile.i is an "unrecognized extension", and cl.exe assumes it is an "object file" resulting in a "no-operation". (See Microsoft warning: http://msdn.microsoft.com/en-us/library/zfsbakc5(v=VS.90).aspx, this warning is active for MSVS 2005, 2008, 2010).
I can't find a switch to state that it is a "source file" (not an object file). The related question explicitly used the "MyFile_preprocessed.cpp" convention, but I'd really rather stay with the (more-universal) MyFile.i convention.
QUESTION: Is there a flag where I can compile a MyFile.i with MSVS?
cl.exe has these two flags
/Tc<source file> compile file as .c
/Tp<source file> compile file as .cpp
that lets you compile files with arbitrary extension as c or c++ files
I tried compiling a main.i with the following contents
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world \n";
return 0;
}
with cl /Tp main.i and it works as advertised