How to use static library that contains C++20 modules - c++

I have a static library project UserInterface that contains the following module:
// Foo.ixx
export module Foo;
export void MyFunc();
void MyFunc()
{
[]() {};
}
The module Foo is imported in the main header of the library like this:
// NuiLibrary.hpp
#pragma once
import Foo;
// Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
// other includes
I cannot build the solution, I can build the static library but in my Sculpt project that references the library I get these errors:
After much search I think it's because modules need to be included explicitly in the client solution by setting Additional Module Dependencies.
What's the syntax for it ?
Why doesn't it just work despite setting this:

What was the cause ?
After a day of trying my specific problem was that the Microsoft Package Server was file locking the .ifc file causing the could not find module error.
How to detect ?
You can find out if you have this issue by trying to compile the module just by itself via right click module -> Compile. It will then fail to compile the file with the error could not open the file another process is using it.
The (non)solution
In a fit of rage I just set everything to default in my static library project setting and now it just works.
What can definitely cause this
When you configure your solution you must do the following:
in the client project add a reference to the static library project (this will remove the error from the client project)
in the static library go Project Settings->C/C++->General and tick the Scan sources for module dependencies (this will remove the error from the library project)
Other Issues
In the older versions of Visual Studio 2019 when you renamed a file from .hpp to .ixx the compiler would still recognize the file as a header file.
To fix this go to the file properties and set the Item type to C/C++ compiler instead of C/C++ header.
In the current version of Visual Studio 2019 when you create a module file you need to go to file properties C/C++->Precompiled headers->Precompiled Header and click Not using precompiled header.
This will fix the following nasty error:

Without having any experience with modules in Visual Studio, I can still see some strange stuff.
Header files should not be used together with modules as we see with your NuLibrary.hpp file. While the syntax looks okay you get problems if that header is included inside the global module fragment (GMF) of other source files that declare modules because import declarations may not appear inside GMF:
// some source file including your header
module;
#include "NuLibrary.hpp" // --> ERROR! import declaration..
What I would recommend is to completely forget the idea of having a "main header" of a module project and instead place all that functionality in a module interface file for your project:
// NuLibrary.cpp
module;
// Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
// other includes
export module nulibrary;
import Foo;
[...]
I suppose Visual Studio would prefer if you have that file the .ixx-extension..

Related

Importing a C++ module from an external shared library (error C2230)

I've got 2 C++ project in the same Visual Studio solution: Engine, a library; and Test, that uses the Engine library
Engine compiles correctly on Windows and produces a lib and a dll. The lib is correctly given to the linker of Test as well
In Test, I try to import a module from Engine, but the compiler fails with error C2230
Here are code excerpts from the 2 projects:
Engine > hal.ixx
export module hal;
#ifdef TEST_ENGINE_EXPORTS
#define TEST_ENGINE_API __declspec(dllexport)
#else
#define TEST_ENGINE_API __declspec(dllimport)
#endif
import <string>;
export extern TEST_ENGINE_API void prepareMain();
export extern TEST_ENGINE_API int init();
//...
Test > main.cpp
#include <cstddef>
#include <stdio.h>
import hal; //fails here: error C2230 could not find module 'hal'
int main(int argc, char const* argv[])
{
prepareMain();
// some other stuff...
}
I'm using Visual Studio 2022 (v. 17.4.0), and for the 2 projects, I compile with std::c++latest, /permissive- and /experimental:module. I've also added the Engine header's folder as Additional include directory for the Test project.
I've tried to remove the module altogether and including headers files in Test and functions are correctly called
I already read this question (How to import a c++ module from another library?) that has the same problem that me, and the article linked in one comment (VS2019 Modules), but I fail to see how it can solve my problem
EDIT
So, I ran a couple of tests, and basically, it seems to stem from the fact that my library is a dll project
I tried making a new solution with 2 projects
The library one is a WindowsStaticLib project. Compiler options are : /std:c++latest, /std:c17, /permissive-, /experimental:module, and /sdl and /W3 (last 2 where there by default, I let them as they were). I deactivated precompiled headers since it seemed to interfere with modules (compliling amodule unit with /exportHeader as it is recommended here when module import standard header was causing VS to start looking for pch.h in header)
For the actual project using the library; library project is added as a reference, compiler options are the same as the library project, lib headers directory is added to VC++ directories > External include directories, lib folder to Library directories, and .lib file added as an Additional dependancy
Everything works.
Module is correctly found and imported, and functions can be called from the actual project.
As a side note, I should add that I didn't need to specify my module functions as extern for them to be usable in the other project main.cpp. I thought I should have done it but apparently not.
Now I tried to do the same thing but with a DLL project for the library. New solution with 2 project, with the exact same configuration as it was for the previous solution.
Error C2230 when I try to import my module in the actual project main.cpp.
Does anyone know something about this ?
Is it normal behaviour that I just didn't know ?

Custom Framework using static lib - Include of non-modular header inside framework module Xcode 9

I have seen plenty of answers around about the issue but non of them are based on my case and "ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES" does not work either.
I am developing a framework that is an implementation of a C library. The library is OpenHome and after compiling it and creating the fat libs I have a folder with all the .a and the headers.
Since It has a folder for "Debug" and "Release", I copy this 2 folders in the root of my project, I import the .a files into my "Link binary with libraries" and, in the "Build Settings" of my target, I set the "Header Search Path" with the location of the headers folder.
for importing all the Headers I need to implement I use a c++ class called "MyHeaders.hpp & MyHeader.cpp", I make the the .hpp pubic and I import it like that in my MyFramework.h (Umbrella file):
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdocumentation"
#import "MyHeaders.hpp"
#pragma clang diagnostic pop
MyHeaders.hpp:
#ifndef MyHeaders_hpp
#define MyHeaders_hpp
#include <stdio.h>
/*** CP -PROXIES- ***/
/** Header That Includes all the CP Related Headers **/
#include "OpenHome/Net/C/CpStack.h"
/** CP Services **/
/*UPnP*/
#include "OpenHome/Net/C/CpUpnpOrgConnectionManager1.h"
#include "OpenHome/Net/C/CpUpnpOrgRenderingControl1.h"
#include "OpenHome/Net/C/CpUpnpOrgAVTransport1.h"
#endif /* MyHeaders_hpp */
The error come from each include. I have replaced wit import but it also doesn't work.
It is worth mentioning that this project configuration was the one I used in the project (Single View Application) I started implementing and testing. The only difference was the existence of the bridging header.
Any Ideas?
Well after a researching i found the issue and the solution
When I am #include "OpenHome/Net/C/CpUpnpOrgConnectionManager1.h" this header is either not public or contains non public headers.
The solution for importing this headers in a Swift based framework is to to create a Module.
I have created a folder "MyModuleFolder" in my target folder and I have created a "module.modulemap" file inside that looks like
module OHNet[system]{
header "MyHeaders.hpp"
export *
}
After that, in "Build Settings" -> "Swift Compiler - Search Paths " -> "Import Paths" i have added the location for "MyModuleFolder".
Finally,
import OHNet
in each swift file
I hope it helps.

How to use another project namespace?

I'm trying to include a namespace from another project in my project but I get the "symbol could not be resolved" error.
using namespace project;
^ This line gives the "symbol could not be resolved" error.
I have the files with this namespace included in my project.
I'm using eclipse on ubuntu Mate.
The C++ compiler does not know about the project management of your IDE (development environment).
It only sees the source code itself. If you add an #include statement the compiler will also see the included code as if it has been put at that place. #include is recursive, so if one included file includes another that will be seen as well.
The error message means that at the point of your using namespace project the symbol project is not known. So, you obviously miss an earlier #include statement including any header of the other project which contains a namespace project { ... } defining the namespace.
Any implementation (.cpp) file using namespace project needs such an #include statement.
To use a namespace of another project, u have to refer that project in your existing project.
In eclipse, you can add the project by following below steps.
Right click > Properties > C/C++ General > Paths and Symbols
Go to Tab Library and Add new library path
You can see the referenced path, check the project and Apply.
You can now use the namespace.
This Link can give more info about references and other settings of the project in eclipse.

Configuring Visual Studio to work with Boost.Python and Python 3

I had Microsoft Visual Studio Community 2013 (Version 12.0.31101.00 Update 4) and Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017) on my PC with Windows 10 Pro.
In order to try examples with Boost.Python I downloaded boost 1.64.0 and build libraries by b2 with options --with-python --toolset=msvc --build-type=complete. As a result I have the following files:
boost_python3-vc120-mt-1_64.dll
boost_python3-vc120-mt-1_64.lib
boost_python3-vc120-mt-gd-1_64.dll
boost_python3-vc120-mt-gd-1_64.lib
libboost_python3-vc120-mt-1_64.lib
libboost_python3-vc120-mt-gd-1_64.lib
libboost_python3-vc120-mt-s-1_64.lib
libboost_python3-vc120-mt-sgd-1_64.lib
libboost_python3-vc120-s-1_64.lib
libboost_python3-vc120-sgd-1_64.lib
Then I created project (type: Win32 / DLL) in Visual Studio with the following code taken here:
char const* greet()
{
return "hello, world";
}
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello)
{
using namespace boost::python;
def("greet", greet);
}
In project properties for C/C++ settings I added "Additional Include Directories" to locations of Boost and Python (ends with \Python36\include).
During the first attempt to build the project an error appears:
Error 1 error LNK1104: cannot open file 'python36.lib'
So in project properties for Linker settings "Additional Library Directories" I added corresponding location (ends with \Python\Python36\libs). After that I could move on ... to the next error:
Error 1 error LNK1104: cannot open file 'boost_python-vc120-mt-gd-1_64.lib'
It is noteworthy that the difference in filenames I had and VS2013 looking for is just digit 3 after word python.
Similar questions at stackoverflow and in google groups are discussed but without valuable tips. The only useful information is that library file names *boost_python-* corresponds to Python 2 and *boost_python3-* to Python 3.
I noticed that changing the build type (Solution Configuration) from Debug to Release leads to change the error message in part of library file name (there is no -gd- now):
Error 1 error LNK1104: cannot open file 'boost_python-vc120-mt-1_64.lib'
I suppose, VS2013 knows boost library file name convention, but probably does not know the difference about Python 2 and Python 3.
So, I have 3 questions:
Is it possible to influence the logic used by VS to look for Boost.Python library? (Of course lib-files renaming is also an option, but I do not like this for some reason)
Do the linker options allow specifying lib-file directly? (i.e. I can write whole path to the boost_python3-vc120-mt-1_64.lib including file name, not just folder name in section "Additional Library Directories")
What option in the project properties should make VS2013 to use different LIB or DLL files, e.g. libboost_python3-vc120-mt-1_64.lib or boost_python3-vc120-mt-1_64.dll instead of boost_python-vc120-mt-1_64.lib?
With the community help I have found answers to couple of the questions.
Is it possible to influence the logic used by VS to look for Boost.Python library?
Name of library depends on value defined as macro BOOST_LIB_NAME in file boost/python/detail/config.hpp.
I have tried to change line (108 in boost 1.64.0)
#define BOOST_LIB_NAME boost_python
to
#define BOOST_LIB_NAME boost_python3
And desirable library file changed from boost_python-vc120-mt-1_64.lib to boost_python3-vc120-mt-1_64.lib.
It should be noted, that instead of changing values in config.hpp file auto_link.hpp can be created and used with redefinition of BOOST_LIB_NAME.
What option in the project properties should make VS2013 to use different LIB or DLL files, e.g. libboost_python3-vc120-mt-1_64.lib or boost_python3-vc120-mt-1_64.dll instead of boost_python-vc120-mt-1_64.lib?
That is also regulated by defines.
In particular, adding to the beginning of my code (before #include <boost/python.hpp>) the line
#define BOOST_PYTHON_STATIC_LIB
forces MSVS to search file libboost_python3-vc120-mt-1_64.lib (or libboost_python-vc120-mt-1_64.lib), i.e. static lib.
And vice versa line
#define BOOST_PYTHON_DYNAMIC_LIB
or
#define BOOST_ALL_DYN_LINK
can be used to import code from a dll.

Include <string> not found compile error in Xcode 4.2

I'm getting include not found compile error in XCode. I have an iOS app project that i use Objective-c and c++ as mix.
Initially, i created one .h file and one .cpp file in my ios project. Then, I renamed the .cpp file to .mm file.
Here is my .h file;
TestLog.h
#ifndef CalculatorDemo_TestLog_h
#define CalculatorDemo_TestLog_h
#include <string>
using namespace std;
class TestLog
{
private:
string logString;
public:
void Log(string logMessage);
};
#endif
TestLog.mm
#include "TestLog.h"
void TestLog::Log(string logMessage)
{
//this->logString->append(logMessage);
}
What am I missing? Do I need to add std c++ library to my targetS? Something related to Search Header Paths?
I just need to use string type.
Thanks much for in advance
select project -> build setting -> apple LLVM compiler 5.1 -> language
In Compile Sources As change to Objective-C++
There's a quirk in XCode. I noticed it in 7.3. Most projects recognize .mm files and the STL, while one project I had did not. The fix was that I had to click on the top-left project icon, then click Targets > Build Phases > Link Binary with Libraries > and add in AppKit.framework. Next, I had to click Targets > Build Settings > search on "Compile Sources", and set it to "Objective C++" on all possible columns. Then, do a Clean and then a Build from the Product menu. This compiled properly then. Then, go back to that Compile Sources again and set it back to "According to File Type" on all possible columns. Then, click Build from the Product menu again. At that point, it compiled properly and allowed me to utilize the "according to file type" option, which I like better.
Oh, and if doing Cocoa stuff, don't forget to add the following header in your files:
#import <Cocoa/Cocoa.h>
And if doing command line stuff, don't forget to add the following instead of the Cocoa header:
#import <Foundation/Foundation.h>
i believe you need to include the whole path to the library. similarly to say "foundation" & "uiview" frameworks.
#import <Foundation/Foundation.h>
or
#import <UIKit/UIKit.h>
and yes, make sure you add the library to your target.
So I was having this issue with the Cocoapods library Bypass and none of these solutions did anything. The problem was with a file which Cocoapods creates called an umbrella header. This is located in <POD_NAME>/Support Files/<POD_NAME>-umbrella.h. Delete it, and it should build just fine.
Now for the explanation of why this is necessary: the umbrella header is mixing both C++ and Objective-C code directly in a header which is a big no-no apparently and ends up completely breaking the C++ imports. By removing it (which seems to have no effect?) this conflicting import which Cocoapods unknowingly created will go away.
Ran into this with xcode 12.4 with a project that is objective-c, but where I need one C++ modul. Solution: wrap the contents of the .h file in:
#if defined __cplusplus
declarations
#endif
Apparently xcode is not good at detecting a mix of sources.
see Expected ; after top level declarator, error in xcode
This often happens when Xcode doesn't understand that a C++ header file you've imported into Objective-C is actually for C++ code.
So you can solve this problem by finding the Objective-C file that imports C++ code, and simply change its extension from .m to .mm