How to use Clang with C++ Modules in Windows 10 - cmake

I wanted to start testing and learn modules and move out of the days of header files and see if the experience differs. I installed everything required (Visual Studio module option in the installer), but Clang doesn't seem to be able to resolve the imports. When I switch over to MSVC on the other hand, it works fine. I'm currently working with VS 2019 Insider preview.
So, how so I get clang (10, the latest release) to work?
EDIT: The error in question is module not found with Clang. MSVC works fine. What flags do I need to pass to Clang so that it can find the modules installed my VS-Installer? For example, I pass CLI argument to MSVC to enable modules.
EDIT:
C++ File (main.cpp):
import std.core;
int main() {
std::cout << "Hello CMake from C++20!\n" << std::endl;
return 0;
}
CMake file
cmake_minimum_required (VERSION 3.16)
project ("cpp20" LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
add_compile_options(
"$<$<CXX_COMPILER_ID:MSVC>:/experimental:module>"
)
add_executable (cpp20 "main.cpp" )
add_compile_options(
"$<$<CXX_COMPILER_ID:MSVC>:/experimental:module>"
# something here to let Clang use modules. I tried -fmodules,
# -fmopodules-ts, -fbuiltin-module-map, -fimplicit-module-maps CLI, but none work.
)
So, how do I get Clang to find the modules install by VS, or modules that it might have installed.
Here is a zip of the sample "Hello World" project.
Thank you.

CMake does not support C++ modules. Once it is officially supported, you can expect it to work. Until than, the compiler or msbuild might do some magic, but you cannot rely on it.

add_compile_options("-fmodules -fbuiltin-module-map")
add_link_options("-fmodules -fbuiltin-module-map")
and you can use standard library modules, but not make your own, this requires more steps and they are not supported by cmake at this point.

Related

CMake TARGET_RUNTIME_DLLS is empty

I have git cloned, built (with MSVC for both Debug and Release) and then installed wxWidgets:
cmake -B build wxWidgets
cmake --build build --config <CONFIG>
cmake --install build --prefix my_install --config <CONFIG>
with <CONFIG> = Debug and <CONFIG> = Release.
Then I used the following CMake script to link against it, as suggested by the wiki:
cmake_minimum_required(VERSION 3.16)
project(Test)
add_executable(Test WIN32 Main.cpp)
# wxWidgets
SET(wxWidgets_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../thirdparty/my_install)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
target_link_libraries(Test PRIVATE ${wxWidgets_LIBRARIES})
# Copy runtime DLLs to the directory of the executable.
add_custom_command(TARGET Test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Runtime Dlls: $<TARGET_RUNTIME_DLLS:Test>"
)
My goal is to automatically copy the DLLs into the directory of the built executable, so that they can be found at runtime. For that I'm using the TARGET_RUNTIME_DLLS generator expression (follwing the sample code in the docs). In the code above, I only print out the expression at build time for testing purposes. The problem is that it is empty.
The approach worked for me before when installing and linking SDL, but SDL provides package configuration files which create imported targets, defining the DLL location(s) via IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG. For wxWidgets one is apparently supposed to use the FindwxWidgets.cmake script shipped with CMake, which sadly doesn't define the produced binaries. Maybe that's why TARGET_RUNTIME_DLLS isn't populated.
Does anyone know, either how to get TARGET_RUNTIME_DLLS filled or how to obtain the list of built wxWidgets DLLs for the current configuration (Release/Debug) post build copying?
Thanks a lot in advance!
I am dealing with a similar problem.
First sanity checks:
You have to work on windows platform otherwise this feature does not
work.
Your Cmake is 3.21 or above
Next comes fuzzy part. I think the library that you are trying to include have to be a Shared Imported library and you have to set a set_target_properties for IMPORTED_IMPLIB which is a path to a .lib file of sort (dll import library, I think it is called) So you have to make sure that it is all set in the package library that you trying to link with your executable.
If you have those dll avaiable and you just want to use them and not actually build them then you can write your own cmake script that will do just what I said above. Then you can include that cmake file in your project and then link against your app.
Note: I also work on similar issue right now and what I just said have not been working very reliably. I got some dlls to be copied and some do not.
Edit:
Cmake docs give a more detailed explanation on how this library setting should look like if you use find_package feature.
Found here: https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries
An UNKNOWN library type is typically only used in the implementation
of Find Modules. It allows the path to an imported library (often
found using the find_library() command) to be used without having to
know what type of library it is. This is especially useful on Windows
where a static library and a DLL's import library both have the same
file extension.

How to Externally, Dynamically Link Lua into a WinAPI/C++ Visual Studio 2019 Project with CMake

Background
I'm currently dabbling in the world of game programming, and following an online guide from bell0bytes. Right now I'm working on this tutorial: https://bell0bytes.eu/lua-and-game-settings/
Therein, the writer suggests "Avoiding DLL Hell" by simply placing the Lua DLL in the local project directory, but that's sloppy, IMO. I've recently started a career as a software engineer (primarily C++) and my team uses CMake and VS to manage our product. I'm confident in my C++ skills and in using VS, but I'm far from mastering CMake, and I'm trying to improve my skills across the board by maintaining a similar dev environment to my work environment for this personal project, meaning that putting the DLL into my driver/project directory and calling it a day isn't sufficient here.
So indeed, we're off to DLL Hell.
System & Versioning Information
OS: Microsoft Windows 10 Pro (10.0.18362 Build 18362)
Sys: x64 Desktop
VS: Microsoft Visual Studio Community 2019 (16.5.4)
CMake: CMake (3.17.1) (Windows x64 Executables for Attempt 1, Source Code and Makefiles for Attempt 2)
Lua: Lua (5.3.5)
Relevant Directories: ../dev/<myprojectdirectory>/, ../dev/resources/
Goal
I want to write the line #include <lua.h> or #include <lua.hpp> or something to that effect in my driver (.cpp / WinMain file) such that I can access the data structures and methods within that Lua header, with the stipulation that this dependency needs to be managed by CMake external to my project, meaning no Lua files end up copied into my working project directory (i.e. Not in here: ../dev/<myprojectdirectory>/ , or any of its subdirectories (excluding maybe <myprojectdirectory>/build/ (CMake generated bin) directory... assuming someone can explain why that's acceptable, from a professional / software engineering standpoint)).
Attempt 1
Originally I grabbed the x64 binaries for Lua from here: http://luabinaries.sourceforge.net/download.html
and after extracting the compressed content, I put the DLL here: ../dev/resources/Lua/lua53.dll
which I'm good with. A solution in which CMake grabs that DLL from my resources directory, and links it into such that IntelliSense can actually find the lua header, such that I can write the following code (from the guide I referenced earlier):
// BEGIN This is my driver
#include <windows.h>
#include <lua.hpp>
#pragma comment(lib, "liblua53.a") // Fairly sure I wont need this line if Lua is linked correctly
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
lua_State *state = luaL_newstate();
lua_close(state);
return 0;
}
// END my driver
and successfully compile my bare bones project, would be perfect.
Attempt 2:
Alternatively a Statically linked solution that works something like the following would be fine too:
I searched stackoverflow and found this, which made me hopeful at first:
Download and build Lua with modern CMake
After adjusting the following code, provided by the OP from the above thread:
cmake_minimum_required(VERSION 3.10)
include(ExternalProject)
ExternalProject_Add(lua
URL "https://www.lua.org/ftp/lua-5.3.5.tar.gz"
CONFIGURE_COMMAND ""
BUILD_COMMAND make generic
BUILD_ALWAYS true
BUILD_IN_SOURCE true
INSTALL_COMMAND ""
)
add_library(liblua STATIC IMPORTED)
ExternalProject_Get_property(lua SOURCE_DIR)
message("liblua will be found at \'${SOURCE_DIR}/src\'")
to my needs, my top level, bare bones CMakeLists.txt file ../dev/<myprojectdirectory>/CMakeLists.txt looks like this:
# BEGIN This is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.2.3)
project(<myprojectname>)
cmake_minimum_required(VERSION 3.10)
include(ExternalProject)
ExternalProject_Add(lua
URL "https://www.lua.org/ftp/lua-5.3.5.tar.gz"
CONFIGURE_COMMAND ""
BUILD_COMMAND make generic
BUILD_ALWAYS true
BUILD_IN_SOURCE true
INSTALL_COMMAND ""
)
add_library(liblua STATIC IMPORTED)
ExternalProject_Get_property(lua SOURCE_DIR)
message("liblua will be found at \'${SOURCE_DIR}/src\'")
add_executable(${PROJECT_NAME} WIN32 <projectsource>)
# END my CMakeLists.txt file
I configured CMake(no errors/warnings) + generated, and finally opened the newly created VS project, thinking that I could #include <lua.h> / #include <lua.hpp> (statically, I think?) with no further trouble, but that didn't work, VS/IntelliSense didn't find the header.
Closing Remarks:
Eventually, I couldn't find anything else to try, or any more clues (I looked through documentation for Lua and CMake on their respective websites for instructions as well). So, stuck in Hell for the first time in quite a while, I decided it was about time I start an account with stack, and query the community.
The solution I'm looking for (of course) gets me to the point where I can use Lua cleanly (preferably dynamically, but statically would be Ok, without manually adjusting any project properties from VS) (If possible please include full code/files for CMakeLists.txt, or C++ drivers, not just snippets, with explanations).
Finally (and importantly), I'm much more interested in an explanation surrounding DLLs, static libraries, CMake, correctly establishing VS project dependencies & linking via CMake, and hopefully, an explanation of where/why I fell short on these two attempts.
Thanks!
Other Stack Exchange Resources I've Reviewed In My Quest For the Answer
Building 64bit application with makefiles using cmake-gui
How do I set the path to a DLL file in Visual Studio?
How to use external DLLs in CMake project
Ideal way to include headers from a DLL?
Unable to find Lua headers with find_package in cmake
Download and build Lua with modern CMake
~ I'm not stupid, but you're welcome to explain it to me like I'm 3. I want to understand, not just get the answer.

CMake idiom for overcoming libstdc++ filesystem weirdness?

If you build C++14 code with G++ and libstdc++, there's a library named libstdc++fs, which is separate from the rest of libstdc++, and contains the code for std::experimental::filesystem. If you don't link against it, you'll get undefined references.
The "trick" I'm using for overcoming this right now is:
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CXX_FILESYSTEM_LIBRARIES "stdc++fs")
endif()
and later:
target_link_libraries(my_target PUBLIC ${CXX_FILESYSTEM_LIBRARIES})
but - I don't like having to place this code in every project I work on. Is there a simpler or more standard idiom I could use? Some way this will all happen implicitly perhaps, with some CMake behind-the-scences magic?
tl;dr: Nothing right now, wait for a newer CMake version
As #Pedro graciously points out, this is a known problem, and there is an open issue about it at KitWare's GitLab site for CMake:
Portable linking for C++17 std::filesystem
If using CMAKE_CXX_STANDARD=17 and std::filesystem, GCC requires linking of an extra library: stdc++fs. ... If C++17 is enabled, would it be worth automatically linking to stdc++fs for GCC versions which require this? Likewise for any quirks in other compilers or libraries.
The KitWare issue is about C++17, for which apparently you still need the separate extra library (i.e. it's not just because of the "experimentality" in C++14). Hopefully we'll see some traction on this matter - but
Note: If you're experiencing this problem with C++17's std::filesystem, you're in luck - that code is built into libstdc++ beginning with GCC 9, so if you're using g++ 9 or later, and std::filesystem, you should no longer experience this problem.

Cuda CMake 3.10 CMakeLists.txt

I have a visual c++ project which creates a dll.
For this project I have a working CMakeLists.txt.
Now I created two cuda source files which complete the project and
with visual studio the build works fine.
I want to add the matching commands to my cmake file.
Can anyone tell me the basic commands I need to add?
I try to build a dll library where i use .cu and .cpp files....
The important part of my cmake file looks like:
# ----------------------------------------------------------------------------
# Set Cuda properties
# ----------------------------------------------------------------------------
enable_language(CUDA)
set(CUDA_SEPARABLE_COMPILATION ON)
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
if (CMAKE_SIZEOF_VOID_P MATCHES 8)
set(CUDA_64_BIT_DEVICE_CODE_DEFAULT ON)
endif()
set(CUDA_NVCC_FLAGS "-gencode arch=compute_50,code=sm_50;-rdc=true;-use_fast_math")
message(STATUS "CUDA_PROPAGATE_HOST_FLAGS: ${CUDA_PROPAGATE_HOST_FLAGS}")
message(STATUS "CUDA_HOST_COMPILER: ${CUDA_HOST_COMPILER}")
message(STATUS "CUDA_NVCC_FLAGS: ${CUDA_NVCC_FLAGS}")
# ----------------------------------------------------------------------------
# Create shared library project
# ----------------------------------------------------------------------------
add_library(${LIB_NAME} SHARED ${HEADERS} ${SOURCES} ${CUDA_SOURCES})
set(CUDA_LIBRARIES "cudadevrt.lib;cudart.lib")
target_link_libraries(${LIB_NAME} ${CUDA_LIBRARIES})
But it doesn't compile the cuda files with the right flags.
Also in visual studio the preprocessor definitions are also in the cuda part of the properties....any suggestions?
I'll try to answer this question using the discussion from the comments and add some extra information.
First of all, there are two ways to enable CUDA support in CMake. One is the old FindCUDA module, and the other is the new built-in CUDA language support added in CMake 3.8, and explained here.
You can choose one or the other (but you'll probably want to use the built-in support for new projects), but then you have to stick with your choice.
To use built-in support you either add it to the project(...) statement or use:
enable_language(CUDA);
To use the old FindCUDA package, you would use:
find_package(CUDA);
Note that the two options use completely different variables for setup. To see what variables are supported by FindCUDA see this page, and for built-in CUDA support see this (don't forget that the <LANG> placeholder can be replaced by any language, which means that CUDA is also one of the available substitutions).
E.g. with FindCUDA you would use CUDA_NVCC_FLAGS to set the compiler flags manually, and with built-in language support you would use CMAKE_CUDA_FLAGS for the same purpose. As a rule of thumb: if the variable starts with CUDA_ it is a part of the FindCUDA package, and if it starts with CMAKE_, then it is part of built-in support.

Program "g++ not found in path" in Eclipse Juno CDT in Ubuntu

Eclipse June CDT reports g++ not found in path, how to fix this?
Typically, g++ will be installed when gcc (GNU Compiler Collection) is installed.
First confirm that you have g++ installed.
You can check this by typing the following in a terminal: which g++.
The response ought to be /usr/bin/g++.
If you find g++ installed, in eclipse go to project->properties->C/C++ Build->Discovery Options, under tools GCC C++ Compiler, put the exact path to g++ instead of g++ (if g++ alone does not work).
You will find this link useful:
What is the difference between g++ and gcc?
If you still have problems, do get back with feedback.
I had similar problem and it is solved by
Installing g++ The GNU C++ complier using ubuntu software centre and
Changing in -
Window -> Preferences -> C/C++ -> Build -> Settings -> Discovery -> CDT GCC Build in Complier Settings [Shared]
From: ${COMMAND} -E -P -v -dD "${INPUTS}"
To: /usr/bin/${COMMAND} -E -P -v -dD "${INPUTS}"
I hope it helps. I think if you add it to the project as mentioned in the first answer, you will need to add all the time for new projects. And if you add as I wrote you don't need to add it for new projects.
I have exactly the same problem. I never had problems with eclipse before under linux and now it wont even compile code. I tried to change the name of the g++ and gcc compilers to their exact location in project->properties->c/c++ Build->discovery options etc. nothing helped, I tried to reinstall eclipse and did an initialize, added the path to the variables etc.. Nothing worked so fare. The project I am working on is quiet big and I rather would like eclipse to manage the source and makefile, instead of doing it manually
Linux Mint 15 Eclispe: Version: 3.8.1 (I tried it with the latest version as well ... nothing changed)
g++ --version g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
gcc --version gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
example:
#include // not resolved using namespace std;
int main() {
std::cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
Well the code above is not what bothers me, as I can fix it by adding the includes of the exact c++ include path, but the code just wont compile. Wired enough eclipse gives me the error:
Description Resource Path Location Type Program "g++" not found in PATH Preferences, C++/Build/Settings/Discovery, [CDT GCC Builtin Compiler Settings] options C/C++ Scanner Discovery Problem
but it appears to me to be possible to compile single files, by opening them and pressing crt+b, but the whole project wont compile.
Fixed the problem this morning:
- got the latest eclipse
- created a new workspace
- created a new project
after a few seconds the very same error disappears
This issue was fixed for me once I deleted eclipse's .metedata folder, called eclipse -initialize from the command line and started eclipse again. HTH
Creating a new Workspace directory on Eclipse startup solved the problem for me.