Previously I've worked on the project using Eclipse. There, I'd import an xml file with <includepath> directories and <macro> defines into "paths/symbols" project settings and that would've been enough to index everything. I did a similar trick with VSCode and QtCreator, and it worked as well, but indexing was too slow compared to Eclipse.
Now I'm trying to import the same project into CLion. I'm not planning to build it, I only want the indexing to work. I've added all the local and external folders into the CMakeLists.txt using include_directories and just copying all the paths from my Eclipse config. At first it wouldn't index anything at all. After I marked the "src" folder of my project as "Project Sources and Headers", it seems that now it indexes source/header links, but it still ignores anything specified in the CMakeLists file. How do I force CLion to index all of all the external include paths without actually building? Basically it's set up with mingw, and it's fine with using mingw gcc, g++ and make, and it just fails to do anything without showing any kinds of errors.
The current CMakeLists.txt file looks like...
cmake_minimum_required(VERSION 3.10)
project(GRP)
set(CMAKE_CXX_STANDARD 11)
include_directories("${PROJECT_SOURCE_DIR}/src/...") #hundreds of project dirs
...
include_directories("C:/Users/...") #hundreds of external includes
...
For me in this situation right-clicking on project and selecting Reload CMake Project solved the problem.
Related
I'm currently trying to move from Windows 10 to Linux (Pop!_OS), but I'm having trouble getting my C++ Project to compile and run correctly on the latter. My C++ project was created using Visual Studio, where I also specified the include folders, library folders, what should be linked, etc in the solution properties. I now want to switch to writing my code using Neovim and not Visual Studio (or Visual Studio Code) and have tried compiling it via G++. I quickly noticed that my include files weren't recognized, so I tried to use CMake and created a CMakeLists.txt. I tried using both
INCLUDE_DIRECTORIES()
and
TARGET_INCLUDE_DIRECTORIES()
but no matter what path I enter, my included files were not recognized. Even when I used a path to the specific include file that caused the first error, it still wasn't recognized.
My goal would be that I can specify an include folder and a library folder, so that I can just add files and folders in these and that the new files and folders automatically get recognized when compiling (i.e I would not have to edit the CMakeLists.txt in the future). Is that even possible with CMake and if yes, does anyone know where i can find further information about that or does anyone have a CMakeLists.txt file that does this? If no, would I have to specify each and every file and folder in the CMakeLists.txt file and do the same for every new include and library?
Project structure:
Overall folder
\- build
\- include
---> includeFolder1
---> includeFolder2
---> ...
\- libs
---> library1.lib
---> library2.lib
---> ...
\- src
--> main.cpp
--> other .cpp's and .h's
--> other folders with .cpp's and .h's
I've tried compiling with G++ and CMake, but both did not work, no matter what I specified as the include and library paths.
I have found the problem that caused my errors. The problem wasn't with CMake, it was with Windows and Linux specific details. I always received errors like "<foo\foo.h> no such file or directory", which led me to think that CMake couldn't find the include directory or the files in it. The problem, however, is with the include path itself. On Windows, paths can be given with a backslash ('\') but on Linux, paths are denominated with a forward slash ('/'). So in my example, the path to the file was "../foo/foo.h" but my code had "#include <foo\foo.h>". So when migrating a project from Windows to Linux, be sure to watch out for backslashes in your #include statements!
Below is a template CMakeLists.txt, that should be a good starting point if you want to migrate your Visual Studio project to Linux. I've used glfw (+ glad) as an example library:
cmake_minimum_required(VERSION 3.20)
project(ExampleProject)
add_executable(${PROJECT_NAME} src/glad.c src/main.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE include)
target_link_libraries(${PROJECT_NAME} GL dl glfw)
I am working on a C++ application in Visual Studio, using the Visual Studio's CMake project template.
To build my application I only need the header and the external library and I can link it like this:
# CMakeList.txt : CMake project for myapp, include source and define project specific logic here.
cmake_minimum_required (VERSION 3.8)
# Add source to this project's executable.
add_executable (myapp "myapp.cpp" "myapp.h")
# Add TIFF library
set(TIFF_INCLUDE_DIR "C:\\libs\\tiff\\out\\install\\x64-Debug\\include")
set(TIFF_LIBRARY "C:\\libs\\tiff\\out\\install\\x64-Debug\\lib\\tiffd.lib")
find_package(TIFF REQUIRED)
target_link_libraries(myapp PRIVATE TIFF::TIFF)
So far, so good. I can use the tiff library to open, read, write tiff files, etc., and IntelliSense is catching up with declarations in the header files. But, I would like IntelliSense to also be aware of the full source code of the TIFF library. For example, if I am in myapp.cpp and I ctrl+click on TIFFOpen it opens the header corresponding to TIFFOpen, but when I ctrl+click TIFFOpen in the header file, it doesn't go to the corresponding source file, which is the normal behaviour for source files in myapp. This is understandable, since I never told Visual Studio where to find the source files of the external library.
CMake doesn't need to know where the source files of the external libraries are, since it won't build the external library, therefore I guess I don't/shouldn't change anything in CMakeLists.txt
One option (I haven't tried yet, but I'm fairly sure it would work), would be to just include the entire tiff library as a sub-project of myapp. I do have some problems with this solution though:
The external library is not conceptually an integral part of the project, and I don't plan to modify the external library. This is more of a principle issue.
Simply having it as a subfolder in my project makes it a risk of changing something I didn't intend to change.
I don't want to rebuild the external library when I do a rebuild all. I know Visual Studio / CMake is smart enough to figure out that nothing changed and doesn't rebuild, but I would rather have Visual Studio / CMake not even try.
The way I see it, I have to set the directory with the source files somewhere in Visual Studio settings, but still related to the project. My best guess is that the .vs/ProjectSettings.json is the file I need to edit somehow, but honestly, I have no clue.
Alternatively, maybe I could write some command in CMakeLists.txt that doesn't do anything, but triggers the IntelliSense to look in the folder with source files. Again, I have no clue how should I go about this.
In a nutshell, I want IntelliSense to see all source files of an external library, the same way it sees the source files of myapp, without including all source files of the external library as a sub-project of myapp. How should I go about it, if even possible?
If relevant, I use Visual Studio 2019 Community and the CMake it comes with it (3.15).
Regarding your last comment, writing code in comment section is inconvenient so I'll just post it here although not an answer.
libtiff-4.pc is for pkg-config, not cmake, and find_package() can't deal with it directly on Windows and would take some work if you really want to. It might be easier to just write everything manually. Remember to set the tiff.lib and tiffd.lib according to your configuration. You can use CMAKE_BUILD_TYPE variable and if() command such as:
# set build type to release if not specified
if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
endif()
# switch lib to link according to build type
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# for release
set(TIFF_LIBRARY "<your_path_to_installed_lib>/tiff.lib")
else()
# for debug. If you have other configs like relwithdebinfo you can add more
set(TIFF_LIBRARY "<your_path_to_installed_lib>/tiffd.lib")
endif()
Also, remove find_package() and use target_link_libraries() and target_inlude_directories():
set(TIFF_INCLUDE_DIR "<your_path_to_installed_headers>/include")
target_link_libraries(myapp PRIVATE ${TIFF_LIBRARY})
target_include_directories(myapp PRIVATE ${TIFF_INCLUDE_DIR})
You can also skip setting TIFF_LIBRARY and TIFF_INCLUDE_DIR and pass the string directly if you like.
I use Visual Studio a lot and it's my favorite IDE. But package management with cmake on Windows is not as smooth as Linux. Always remember to set environment variables after compiling and installing external libraries.
Normally find_package() will look for a system environment variable named <libname>_DIR (for example TIFF_DIR, which is not found in your case), which is used to store path to installed lib, then look for <libname>Config.cmake and <libname>ConfigVersion.cmake in that folder (and would fail for TIFF since it doesn't have them).
It also searches other places, check https://cmake.org/cmake/help/v3.15/command/find_package.html?highlight=find_package for details.
So for those libs with cmake exported files, add a variable with correct name and value. And that's only for compiling.
If you want your application to run after compiling, you also need to add the path of installed lib's binaries (usually *.dll) to system's Path variable. In your case you should find something like tiff.dll and tiffd.dll after compiling and installation, add that folder to Path and you are good to go.
Actually, showing the source in the IDE is easy enough.
Just add the source with add_library(tiff_for_ide EXCLUDE_FROM_ALL ${SOURCES}) but don't link with it in the main program. You'll want to use a different target name for the library. For this you'd need the source in your project directly or as a submodule (if using Git, something else if available by you VCS).
Other options are using ExternalModule_Add; or FetchContent_MakeAvailable with the add_library as above, to avoid adding third party deps into the repository directly.
Now, just cross your fingers and hope that the IDE is not intelligent enough to restrict searching for sources that are linked against the target which compiles the current file. Or that it's intelligent enough to detect this situation but fallback to searching the whole project files anyway when it's linking against a binary.
I have a cmake file that generate a solution with several sub projects, but I wish a "filter" (VS specific feature) to group all my thirdparty libraries together.
An example, for now I use the ZLIB library, it appear as a project, I use the following:
add_subdirectory(zlib)
To add such filter, I have try the following :
add_subdirectory(zlib)
FILE(GLOB_RECURSE ZLIB_SOURCE "zlib/*")
SOURCE_GROUP("THIRDPARTY" FILES ${ZLIB_SOURCE})
In this example I wish to put the "zlib" project into a "THIRDPARTY" filter.
But nothing is changed in my solution ! I use VS2017 and cmake 3.8
Any idea ?
There are two ways of separating all your own and third-party code of an application in the solution explorer.
Separate multiple Projects and put them into folders which are on top-level.
Do the following:
put this on top of your main CMakeLists.txt
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
after defining your targets add this extra bit
add_executable(MyLib .....)
set_target_properties(MyLib
PROPERTIES
FOLDER "Libraries");
Your project-explorer will then look like this:
credit goes to these guys: http://cmake.3232098.n2.nabble.com/Solution-folders-td6043529.html
To separate multiple source-files inside a project you can do the following:
collect all files of a module with:
set(VARIABLE_NAME src/module/fileName1.cpp
src/module/fileName2.cpp)
make it appear within a filter:
source_group("Source Files\\module" FILES ${VARIABLE_NAME})
group all previously generated filters together:
set(SOURCE_FILES "${VARIABLE_NAME}")
finally make everything appear inside the project explorer:
add_executable(projectName "${SOURCE_FILES}")
The above works for me under CMake 3.6 and Visual Studio 2015, so it should also work with VS2017 and Cmake 3.8.
It looks like this when finished for all files of the project:
Since you are developing with VS here's another hint that I think is very useful:
you can define VS's startup project by the following command. This way you don't have to change anything in VS after remaking the project with CMake.
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ProjectName)
I have a CLion C++ project that has the following structure:
project
---->my_includes
| ----> my_own.hpp
---->source
----> my_app
----> my_src.cpp
The first line of my_src.cpp is
#include "my_includes/my_own.hpp"
I use an external build system that requires this inclusion format. The problem is if I use a function in my source file defined in the included header, CLion says "Cannot find my_own.hpp" if I try to hover over the inclusion.
I tried marking the include directory as containing Project Source or Headers but this didn't fix it. Any ideas?
You need to create a CMakeLists.txt for CLion to be happy. It is enough to declare all the source files, you don't have to convert your scons (or any other build system) to cmake.
You don't even have to write the CMakeLists.txt by hand, you can ask CLion to do it:
File | New CMake Project from Sources... (since CLion 2019.2)
File | Import project ... | (older CLion)
and then point at the directory containing your project.
Now edit the generated CMakeLists.txt and add a cmake command to tell CLion where to find the includes (actually to tell the compiler, and CLion will reuse that information).
Since your source files use the include as #include "my_includes/my_own.hpp", you need to tell cmake the base directory containing directory my_includes:
include_directories(.)
Where the dot means the same directory as the one containing the CMakeLists.txt.
I tested with a project reproducing your layout and from my_src.cpp I can navigate to my_own.hpp.
Then to build you still have to use scons in a console. It is also possible to add a cmake command, add_custom_target() that will call your scons (or your make, or whatever), so that you can also navigate from CLion to the build errors.
This should be a CMake-based project to open correctly in CLion.
Check CMake basics tutorial if you are new to CMake: https://www.jetbrains.com/help/clion/2016.1/quick-cmake-tutorial.html
And for MakeFile + gcc (g++) projects, you can add the flag -I /Dir/To/Your/Project.
If CLion still shows errors with #include after recompiling the make file, delete the .idea folder and restart CLion.
I'm trying to set up PCL with eclipse. I have never did any CMake stuff, so I don't really know what is going on.
I have installed PCL with apt-get. Next, I made folder ~/hello_pcl/src, where I saved pcd_write.cpp file and following CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(hello_pcl)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (pcd_write_exe pcd_write.cpp)
target_link_libraries (pcd_write_exe ${PCL_LIBRARIES})
Next, I've done:
cd ~/hello_pcl
mkdir build
cd build
cmake -G"Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../src
As for the last, I have imported created project into eclipse with File -> Import -> C/C++ -> Existing code as Makefile project.
My problem is: after that, the application runs correctly, but Eclipse code editor marks all includes as Unresolved inclusion and almost every function as Unresolved symbol. Strangely, it does it also with #include <iostream>. I figured out, that it's a problem with indexer. Therefore, I have add /usr/include/c++/4.8 and /usr/include/pcl-1.7 in Project properties -> C/C++ general -> Paths and symbols in Includes tab and GCC C++ language.
It seems to have resolved some of the issues, but there are still functions, that are marked red (see screenshot).
Anyone knows how to solve this problem?
I solved my problem.
It seems, that in this case, typicas workflow for using Eclipse CDT with CMake makes indexer work incorectly.
What I have done is, after invoking cmake command, imported project not as Makefile project, but with Import -> General -> Existing projects into workspace.
After importing project in this way, indexer takes really lot of time (and I suppose it can crush Eclipse, if project is big enough) to parse all includes. But after that everything works fine.