How to get Modules to work in VS2019 16.8? - c++

I'm trying to convert my program to modules. I'm using MSVS 19 Community Edition version 16.8 (also tried with MSVS19CE Version 16.9.01 Preview)
Each .ixx IDF I write compiles fine when compiled indiviually, (with "import"'s and its usage commented out),
Build started...
1>------ Build started: Project: myCare, Configuration: Debug x64 ------
1>Scanning sources for module dependencies...
1>Compiling...
1>DB.ixx
1>Compiling...
1>HS.ixx
1>pch.cpp
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
But when I introduce the commented out imports, suddenly VS can't find the modules it just previously compiled beautifully.
Build started...
1>------ Build started: Project: myCare, Configuration: Debug x64 ------
1>Scanning sources for module dependencies...
1>Compiling...
1>HS.ixx <<<<----- Compiled without errors
1>Compiling...
...
1>ComplexComboBox.ixx
1>D:\Dev\myCare\Modules\ComplexComboBox.ixx(289,1): error C2230: could not find module 'HS'
1>D:\Dev\myCare\Modules\ComplexComboBox.ixx(289,1): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>INTERNAL COMPILER ERROR in 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\CL.exe'
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>Done building project "myCare.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
error C2230: could not find module 'HS'
error C2230: could not find module 'Aui'
error C2230: could not find module 'Ctrl.ListCtrl'
Any hints? Every module has the structure like this (and has the file extension .ixx)
module;
#include "Defines.h"
#include <any>
#include <bitset>
...
export module HS;
namespace HS
{
export enum class Comms { None = 0, Port = 1, Timeout = 2, Authority = 3, Security = 4 };
export auto CommsAuthority(const AuthorityType newValue)->void;
export auto CommsAuthority(void)->AuthorityType;
(Not everything in here is exported)
...
}
module :private;
auto HS::CommsAuthority(const AuthorityType newValue)->void
{
...
}
auto HS::CommsAuthority(void)->AuthorityType
{
...
}
...

This seems to be a bug with the way visual studio currently handles modules imported by other modules. Essentially when each module compiles it creates a <module_file_name>.ixx.ifc file. This is detected perfectly fine when the module is imported into a cpp file but not when importing to a module. removing the .ixx from the filename will import correctly whether importing to another module or a cpp file though.
I solved this in 1 of my own projects through the project properties(the required options are only available in the preview version of visual studio at the moment though).
So you first need to set Module File name to $(IntDir)%(Filename).ifc in C/C++->Output Files
Then set Additional BMI Directories to $(IntDir) in C/C++->General.
Visual studio puts all the intermediate module stuff in the intermediate directory by default but if you'd rather have all your intermediate module things in a separate folder you can set Module Dependencies File in C/C++->Advanced to wherever you want and then update the $(IntDir) bits above to the new location.

Related

How to test a custom module in MSVC's googletest

My project solution is roughly like this:
Project("{xxxxxxxxxxxxxxxx11111111}") = "project1", "project1.vcxproj", "{xxxxxxxxxxxxxxxx222222222222222}"
EndProject
Project("{xxxxxxxxxxxxxxxx11111111}") = "test", "test\test.vcxproj", "{xxxxxxxxxxxxxxxx333333333333333}"
EndProject
Project brief description:
I have two projects, one is the main project, the directory is project/src/balabala.ixx, and the other is the added googletest project, the directory is project/test/balabala.cpp
My requirement is to test whether the module of my main project meets my needs in the sub-project of googletest, but I can't use the module of the main project now, VS tells me that it can't find my module.
like this:
#include "gtest/gtest.h"
import std.core;
// cannot find my module
// import myproject.some_module;
TEST(TestCaseName, TestName)
{
EXPECT_EQ(1, 1);
EXPECT_TRUE(true);
// it works
std::cout << "hello world";
}
I also looked for Microsoft's documentation, and I found
https://devblogs.microsoft.com/cppblog/a-tour-of-cpp-modules-in-visual-studio/#external-modules
But it did not tell how to set the path, no matter the path I filled in is ../ or absolute path VS said that the target file cannot be opened
VC++ Directories -> all module is public -> true also not work :(
==========================================================================
After various attempts to no avail, I decided not to use the subproject. I copied the original include and lib folders of googletest to project/3rd-party/googletest, and then set up additional include directories and additional lib directories.
then I write this:
// project/test/test.cpp
#include <gtest/gtest.h>
// it found my module!!!
import muproject.some_module;
TEST(TestCaseName, TestName)
{
EXPECT_EQ(1, 1);
EXPECT_TRUE(true);
}
But when I choose to run the test case, the compiler outputs the following:
Build started...
1>------ Build started: Project: my_project, Configuration: Debug x64 ------
1>Scanning sources for module dependencies...
1>test.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\sstream(262,1): error C2270: '()': modifiers not allowed on nonmember functions
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\sstream(237): message : while compiling class template member function 'int std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char>>::overflow(int)'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\sstream(905): message : see reference to class template instantiation 'std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char>>' being compiled
1>`path_to_my_project`\3rd-party\googletest\include\gtest\gtest-message.h(232): message : see reference to class template instantiation 'std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>' being compiled
1>d:\a01\_work\3\s\binaries\x86ret\inc\compare(336,31): error C2028: struct/union member must be inside a struct/union
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\sstream(262,1): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>INTERNAL COMPILER ERROR in 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\CL.exe'
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>Done building project "my_project.vcxproj" -- FAILED.
I double-checked the settings (x64/x86/debug/release) and confirmed that the lib settings are correct
gtest-message.h(232): message : see reference to class template instantiation 'std::basic_stringstream<char,std::char_traits,std::allocator>' being compiled
// We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator.
void operator=(const Message&);
// -> this line is line232
========================================================================
It's too strange, this seems to be a probabilistic event. If you don't import std.core, the compilation will generally pass, but once std.core is imported, it will most likely fail to compile (the error is as above) (but occasionally it can be compiled)

How does visual studio (ms compiler) know it needs specific boost libraries

vs2015 community, x64, debug, boost 1.63
New Empty project
Properties->C++->General->Additional Include Directories add
"C:\Program Files\boost_1_63_0" Add new C++ file, Source.cpp:
#include "boost/make_shared.hpp"
#include "boost/thread.hpp"
void main(int argc, char **argv)
{
}
Build Solution
Result:
1>------ Build started: Project: boostLibTest, Configuration: Debug x64 ------
1> Source.cpp
1>LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc140-mt-gd-1_63.lib'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Where is that lib file getting added to the project? It's not boostLibTest.vcxproj, nor the command line for the compiler.
I wanted to write a static library that uses boost that I can access from another app that doesn't have/need boost, but this auto-include-boost-dependency prevents me from doing so.
There are #pragmas that MSVC supports that let a header file state "you need this library".
Boost is apparently using them.
Ideally, boost should only include them in header files that are not "header only". The granularity may not be perfect. But if you only need some enum values and other header-file only data from "boost/thread.hpp", check to see if they are included in a "header-file-only" header.

Visual Studio C++ cannot open some headers I didn't deliberately include

today I wanted to start learning C++.
However I keep getting these errors:
Cannot open source file "stdio.h"
Cannot open source file "tchar.h"
Cannot open source file "SDKDDKver.h"
However, I even get these in a default empty win32 console project.
Does anyone know how to fix this?
OS: windows 10
My default code looks like this:
// HelloWorld.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
int main()
{
return 0;
}
The errors are:
Severity Code Description Project File Line Suppression State
Error (active) cannot open source file "stdio.h" HelloWorld c:\Users\HP\Documents\Visual Studio 2015\Projects\HelloWorld\HelloWorld\stdafx.h 10
Severity Code Description Project File Line Suppression State
Error (active) cannot open source file "tchar.h" HelloWorld c:\Users\HP\Documents\Visual Studio 2015\Projects\HelloWorld\HelloWorld\stdafx.h 11
Severity Code Description Project File Line Suppression State
Error (active) cannot open source file "SDKDDKVer.h" HelloWorld c:\Users\HP\Documents\Visual Studio 2015\Projects\HelloWorld\HelloWorld\targetver.h 8
Severity Code Description Project File Line Suppression State
Error (active) cannot open source file "stdio.h" HelloWorld c:\Users\HP\Documents\Visual Studio 2015\Projects\HelloWorld\HelloWorld\stdafx.h 10
In the OUTPUT window:
1>------ Build started: Project: HelloWorld, Configuration: Debug Win32 ------
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\Win32\PlatformToolsets\v140\Toolset.targets(34,5): error MSB8036: The Windows SDK version 8.1 was not found. Install the required version of Windows SDK or change the SDK version in the project property pages or by right-clicking the solution and selecting "Retarget solution".
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
EDIT:
I believe I have C++ installed, cause first when I went to
file > new > project > Visual C++
It would only show me "Install ... for C++", So I installed one of the first options (don't remember which one it was) and after installing it allowed me to create projects.
Check your stdafx.h contents. Headers can be included transitively. In particular, the three ehaders you quote are in the VC++ stdafx.h for new projects. You can simply remove them if you're programming C++.
(It says something about Microsoft's struggle to choose between C and C++ : They don't support C99, but they default to a C header instead of C++. Not even <cstdio>. )

Building an EXE with Visual Studio 2013

I'm unclear on how to do this. All I can find on the internet is that you build and then the exe will automatically appear in the project file, but that is not the case for me. I just tried setting up an extremely basic C++ project with one main.cpp of this:
#include <iostream>
int main() {
std::cout << "Hey ho!" << std::endl;
}
It runs all nice and well in Visual Studio, but there is no EXE in the project. Am I doing something wrong? Also, for the record, this is the output I get when I build:
1>------ Build started: Project: ConsoleApplication1, Configuration: Release Win32 ------
1> main.cpp
1> Generating code
1> Finished generating code
1> ConsoleApplication1.vcxproj -> c:\users\oysi\documents\visual studio 2013\Projects\ConsoleApplication1\Release\ConsoleApplication1.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Try F5, it will build and run your project. If you put a breakpoint at the closing bracket (}) of main, you'll even see your output in the console.
The .exe won't be added to the project, but it will be created in the output directory. The output you copied here actually tells you, where you can find the .exe:
c:\users\oysi\documents\visual studio 2013\Projects\ConsoleApplication1\Release\ConsoleApplication1.exe
As Visual tells you, you should look for .EXE file in this directory:
c:\users\<username>\documents\visual studio 2013\Projects\ConsoleApplication1\Release\ConsoleApplication1.exe

playing a .wav file

I'm using visual studio 2010 express and I'm trying to write a simple program that will repeat a wave file 5 times(I'm running a windows xp sp3).
This is as far as I got:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
int main ()
{
int a = 5;
while(a >= 1){
cout << "It's a wav file";
PlaySound(L"SomeAudioFile-01.wav", NULL, SND_FILENAME);
--a;
}
return 0;
}
The problem is I keep getting this error message when I'm building it:
1>------ Build started: Project: It's a F**king Country, Configuration: Release Win32 -- ----
1> mycode.cpp
1>..\..\..\..\..\Shaul's documents\Visual Studio 2010\Projects\MyProject\Release\SomeAudioFile-01.wav : fatal error LNK1136: invalid or corrupt file
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The file is perfectly fine and plays with no problems whatsoever outside visual studio.
Help would be truly appreciated.
Instead of adding the WAV file to the project files, add it to the resources and use SND_RESOURCE instead of SND_FILENAME.
You include the sound file as a object file, so the compiler tries to link with it. But it's a binary file that's not linkable (which is what the error message says).
Don't include the sound file in the project, so the environment won't link with it.
P.S. In the future, please refrain from using "bad" words on a public site like this.
To get rid of the linker error, you need to tell the IDE to link with the winmm.lib library also, so open Project/Properties/Configuration Properties/Linker/Input and append winmm.lib in the Additional Dependencies field.
Also, use the following function profile:
PlaySound(L"audio.wav", NULL, SND_APPLICATION);