I'm using coc for code-completion and ale for linting my c++ files, this works fine when I have all my headers and source files in the same directory, however when I have a CMake project with the typical include & src directories (for headers and .cpp files respectively) this setup fails to realize that my headers are in the include directory and so the linting and code completion dont work.
Any help in configuring my neovim setup to handle this project structure, or suggestions of different plugins which would do what I want would be much appreciated.
Please check CMake's documentation regarding CMAKE_EXPORT_COMPILE_COMMANDS.
Here is part of my .nvimrc for example:
nnoremap <F5> :wa <bar> :set makeprg=cd\ build\ &&\ cmake\ -DCMAKE_BUILD_TYPE=debug\ -DCMAKE_EXPORT_COMPILE_COMMANDS=1\ ../view\ &&\ cmake\ --build\ . <bar> :compiler gcc <bar> :make <CR>
This generates the compile_commands.json file which is read by the various ALE Supported Languages and Tools.
There is a nice Plugin cmake4vim which works really fine.
You can e.g. set the name of the build path, run/edit config (incl. the ccmake tool), build within vim, jump to next error, ...
Related
I used to work with VSCode C/C++ extension. there was a feature in this extension(in a json file), called "includePath", which I could set the paths for my headers, so without execution of CMake or make, I would have the suggestion of my headers and code completion from those.
now I have switched to neovim and clangd as the language server for code completion. I searched a lot to find the corresponding feature in clangd options but I could not find anything more than this link.
since the clangd is a powerful language server, I am in wonder if there is not such a feature in it. so I want to know is there actually such a feature in clangd? and if YES how can I use that?
Note: I use a language client, called "coc-clangd". I don't know if it matters or not.
Clangd uses compile_commands.json database file which contains flags (such as include directories) for each file in project. But this file is auto-generated, so all modifications to it will be overwritten eventually. You can ask CMake to add any custom compile flags with -DCMAKE_CXX_FLAGS command line argument.
Example for system headers (#include <file.h>):
cmake -DCMAKE_CXX_FLAGS="-isystem /path/to/includes" /path/to/source
For project headers (#include "file.h"):
cmake -DCMAKE_CXX_FLAGS=-Ipath/to/includes /path/to/source
Additionally, you can set CXXFLAGS environment variable:
export CXXFLAGS="-isystem /path/to/includes"
cmake path/to/sources
After that new flags should appear in your compile_commands.json file.
Maybe this is useful: https://clangd.llvm.org/config
Create a file called '.clangd' in the top-level of the source directory.
Add those content.
CompileFlags: # Tweak the parse settings
Add:
- "-I=[folder]"
But I think this is not recommend, all include directories should be add in CMakeLists.txt file.
You can add includePath to clangd.fallbackFlags into vscode's settings.json like this:
"clangd.fallbackFlags": [
"-I${workspaceFolder}/include",
"-I/my/include"
]
To use code completion provided by Clangd, let Clangd retrieve include paths from compiler_commands.json with compiler calls used by CMake. Set the CMAKE_EXPORT_COMPILE_COMMANDS option in CMakeLists.txt, it will output compiler_commands.json to the build directory when CMake is run:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Copy the generated compiler_commands.json to the project source directory. Clangd will now source this file.
I would like to generate glut .so file in Ubuntu. I've downloaded the files, extracted them and opened the readme. This is the instructions for Linux
MAKEFILE GENERATION TO BUILD GLUT: <-- IMPORTANT!
Use "mkmkfiles.sgi" to put Makefiles using the SGI Makefile conventions
in place. Use "mkmkfiles.imake" to put Makefiles generated from
Imakefiles in place. Run one of these two commands in this directory,
then do a "make".
I don't really understand SGI Makefile. I know Makefile though. Could you please guide me for generating the dll. In the folder, these are the files
adainclude Imakefile mkmkfiles.imake README.fortran README.man
CHANGES include mkmkfiles.sgi README.glut2 README.mesa
FAQ.glut lib mkmkfiles.win README.glut3 README.mui
Glut.cf linux NOTICE README.ibm-shlib README.win
glutdefs Makefile Portability.txt README.inventor README.xinput
glutmake.bat Makefile.sgi progs README.irix6 test
glutwin32.mak Makefile.win README README.irix64bit
IAFA-PACKAGE man README.ada README.linux
I've tried running make but getting errors and there is no CMakeLists. Thank you.
When I run ./mkmkfiles.sgi or mkmkfiles.imake, I get this error
bash: ./mkmkfiles.sgi: /bin/csh: bad interpreter: No such file or directory
Technically you need first to instal tcsh. With that installed, running mkmkfiles.imake will work and generate the required Makefile so you can build on Linux. Here is an old post asking pretty much the same question: http://comments.gmane.org/gmane.linux.lfs.general/17539
I have been struggling with this for quite a while, and my adventures with cmake have only resulted in hackish solutions that I am pretty sure are not correct.
I created a library that consists of several files, as follows:
-libfolder
-codepart1folder
-CMakeLists.txt
-codepart1.cpp
-codepart1.hpp
-codepart2folder
-codepart3folder
-lib.cpp
-lib.hpp
-CMakeLists.txt
I wrote a CMakeLists file to compile the library (after some experimentation), and I can generate a lib.a file. Now I would like to include this code as a library in other projects, and access it through the interface in lib.hpp. What is the best way to do this, in terms of directory structure, and what I need to put into CMakeLists.txt in my root project?
My current attempt has been to add -libfolder as a subfolder to my current project, and add the commands:
include_directories(${PROJECT_SOURCE_DIR}/libfolder)
link_directories(${PROJECT_BINARY_DIR}/libfolder)
add_subdirectory(libfolder)
target_link_libraries(project lib)
When I run make, the library compiles fine, but when project.cpp compiles, it complains that it cannot find codepart1.hpp (which is included in lib.hpp, included from project.cpp).
I suspect that this is the wrong way about doing this, but I cannot wade through the CMake documentation and find a good tutorial on setting up projects like this. Please help, CMake gurus!
The clean way to import one CMake project into another is via the find_package command. The package declaration is done by using the export command. An advantage of using find_package is that it eliminates the need to hard-code paths to the package's files.
Regarding the missing hpp file, you didn't include codepart1folder, so it's not on the include path.
Ok, so after consulting a coworker of mine who is a CMake guru, it seems CMake does not have support for what I am trying to do, leaving one with 3 options:
Add all of the dependencies to the parent projects CMakeLists.txt - not very clean, but it will get the thing to work. You'll have to do this for every project you add the code to, and go back and fix things if your library changes.
clean up your library headers. This is done through some compiler hackery. The idea is to forward-declare every class, and use only pointers or boost::shared_ptr, and then include the dependencies only in the cpp file. That way you can build the cpp file using all the findpackage stuff, and you get the bonus of being able to use the lib by only including the header and linking to the library.
Look into build systems. Having portable code and fast code compilation with complex dependencies is not a solved problem! From my investigations it turned out to be quite complicated. I ended up adopting my coworkers build system which he created himself in cmake, using things he picked up from Google.
Looking at your post you don't seem to add 'codepart1folder' to the includes anywhere. How are you including codepart1.hpp as:
#include <codepart1.hpp>
#include "codepart1folder/codepart1.hpp"
I don't think there is a standard accepted way to structure cmake projects. I've looked at a bunch of cmake repos and they tend to have differences. Personally I do the following:
-project
CMakeLists.txt
-build
-cmake
OptionalCmakeModule.cmake
-src
-Main
Main.cpp
Main.hpp
-DataStructs
SomeTree.hpp
SomeObject.hpp
-Debug
Debug.hpp
-UI
Window.hpp
Window.cpp
Basically that dumps all the source code into 1 directory, then you perform an out of source build with: 'mkdir build && cd build && cmake .. && make' in the projects root folder.
If you have separate libs as part of your project, then you might want a separate libs directory with another subfolder for your specific lib.
I have some of my repos on: https://github.com/dcbishop/ if you want to look at the CMakeLists.txt files.
The main problems with my project structure are that I use the FILE_GLOB which is apparently the 'wrong' way to do things (if you add files after running 'cmake ..' then they won't be picked up hen you do a 'make'). I haven't figured out what the 'right' way to do it is (from what I can see it involves keeping a separate list of files) I also only use 1 CMakeLists.txt file.
Some projects also choose to separate their cpp and hpp files into separate directories. So you would have an include and src folders (at least for the hpp files that are intended to be used externally). I think that would mainly be for projects that are mainly large libraries. Would also make installing header files much easier.
You are probably missing
include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder)
In such a case you might want to set( CMAKE_INCLUDE_CURRENT_DIR on) to add all folders to the include directory path variable.
Check cmake's output on the command line whether the correct include folders are set or not. Additionally you can always use message() as "print debugging" for cmake variables.
In case of include directories however you need to read the directory property to see what is actually in the include directories.
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
message("inc_dirs = ${inc_dirs}")
I hope this helps you figuring out what is missing.
Edit
I just saw your comment about added codepart1folder in the libfolder. It is only available in the libfolder's include_directory path and not propagated to the root folder.
Since the include codepart1.hpp is present in the lib.hpp however you need to have it also available in the project path otherwise you will get missing declaration errors when you build your project.
As a follow up to another question I recently asked, I realize my issue is that I don't know how to include Apple 'frameworks' in the Eclipse CDT project properties so that they're picked up and linked at compile time.
This results in includes in this form not to be resolved:
#include <OpenCL/cl.h>
Where the actual path would be something like:
/System/Library/Frameworks/OpenCL.framework/Versions/A/Headers
And the cmd line option would be (if I was manually compiling):
-framework OpenCL
In summary: How can I get Eclipse to see the framework(s) I want fromt he project properties?
Any help highly appreciated!
An alternative answer to JohnIdol's answer. In particular, an approach that can work in the case that you don't want to change the <OpenCL/cl.h> reference to <cl.h>
First, I came to the site with exactly this question in mind (how to include Apple 'frameworks' in Eclipse CDT (C/C++) projects) and I really appreciate the discussion - it gave me a starting point.
John's answer is cool but it does involve changing how the include file is called (e.g., <OpenCL/cl.h> becomes <cl.h> in the code). Then he does a direct include-path reference in the eclipse properties for each Header directory he needs.
In my case, I had checked-out GNU Backgammon to play around with the source code. This code compiles (with some mods to LDFLAGS and CPPFLAGS before doing the autogen.sh) on the OS X CLI environment using the I-guess-standard apple approach of the -framework option and with include files references like
#include <CoreAudio/CoreAudioTypes.h>
I may never actually commit anything but I didn't want to start hacking the #includes in code that is already compiling just fine using the standard approach. So I did the following:
Made a new directory in my workspace gnubg called "Frameworks".
Inside that directory, make soft-links to the header directories.
ln -s /System/Library/Frameworks/CoreAudio.framework/Headers CoreAudio
In the gnubg project properties > C/C++ General> Paths and Symbols, added /gnubg/Frameworks to the Include directories (as a workspace path). I only had to do this once, regardless of the number of soft links I made.
This way I did not have to change the code at all, Eclipse was happy, CLI compilation was happy as well.
I note that there is a slight wrinkle if using some directories in Frameworks such as the CoreServices.framework. In those cases there is a Frameworks subdirectory and relative path references in some of the include files (e.g., ..) to other include files. So in this case I had to modify the procedure a bit. Basically, I had to add an additional sub-directory in Frameworks for CoreServices.framework and then in that directory I had to add two soft links. One for the CoreServices (for the Headers) and one for Framework subdirectory.
lrwxr-xr-x 1 dhansen staff 57B Jul 27 02:06 CoreServices -> /System/Library/Frameworks/CoreServices.framework/Headers
lrwxr-xr-x 1 dhansen staff 60B Jul 27 02:05 Frameworks -> /System/Library/Frameworks/CoreServices.framework/Frameworks
Then I had to add /gnubg/Frameworks/CoreServices.framework to the include path (step 3 above).
And that's it. No more include file problems.
Since current Eclipse CDT releases don't perform sub-framework header inclusion correctly, you can avoid sub-framework problems (like those generated by the CoreServices header files) by creating symbolic links to the include directories of each sub-framework. I elaborated on this subject, which stems from danhan answer, in the following post:
http://thegreyblog.blogspot.com/2014/02/how-to-include-apple-frameworks-headers.html
In order to automate this process, I've created a Z shell script which automates this process and creates the symlink to the specified frameworks' header directory, together with the links to the include directory of each one of their sub-frameworks. The script can be found here: https://github.com/emcrisostomo/link-osx-framework-headers
Hope this helps.
OK so I had to include like this:
#include <cl.h>
Then add an include to the folder with the header file in Properties > C/C++ General > Paths and Symbols resulting in the following option for the compiler:
-I/System/Library/Frameworks/OpenCL.framework/Versions/A/Headers
And, most notably, had to add the following options for libraries path and framework inclusion under Properties > C/C++ Build > Settings:
-L/System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries -framework OpenCL
The above did the trick.
goto Your Project>Properties>MacOS X C++ Linker>Command
Where "g++" add " -framework OpenCL"
Greetings all,
I am trying to use QT internationalization with CMake.
I have configured my cmake file as follows :
#Internalization - this should generate core_jp.ts ?
SET(rinzo_core_TRANSLATIONS
i18n/core_jp.ts
)
#these are my source files in the project
SET(FILES_TO_TRANSLATE
${rinzo_core_srcs}
${rinzo_core_moh_srcs}
)
QT4_CREATE_TRANSLATION(QM_FILES ${FILES_TO_TRANSLATE} ${rinzo_core_TRANSLATIONS})
QT4_ADD_TRANSLATION(QM ${rinzo_core_TRANSLATIONS})
But it doesnt genereate any TS nor QM files.
My questions -
1.Does Cmake(by using QT tools) generate TS files automatically extracting "tr()" methods from the source ? (that means I dont have to create any TS file and above i18n/core_jp.ts will be genereated automatically)
2.What exacly are QM files ?
Thanks in advance
In CMake documentation see QT4_CREATE_TRANSLATION and QT4_ADD_TRANSLATION macros.
So you should do the followings:
SET(Lang_files
example.ts
)
...
QT4_CREATE_TRANSLATION(LangSrcs ${Lang_files})
...
ADD_EXECUTABLE(project_name ... others sources ... ${LangSrcs})
Translation binary files (*.qm) according to http://itk.org/Wiki/CMake:How_To_Build_Qt4_Software
Also from the bottom of that website
Usage - Updating the .ts files
When you want it to process all your
source files (looking for new texts to
translate), configure cmake to turn on
UPDATE_TRANSLATIONS, and then make
your project. CMake will modify your
.ts files in your SOURCE folders in
addition to generating the .qm files.
WARNING: Be aware that CMake will be updating the source .ts files, which means that if > you do a make clean, it will DELETE your source .ts files!!! So it would be a good idea > to switch off UPDATE_TRANSLATIONS as soon as possible.
My solution relies on manually invoked lupdate and lrelease tools via add_custom_target, so the generated files are not removed on make clean and put into the source directory.
I defined a function that scans provided directory, generates/updates ts files, and compiles them into qm files in the same directory, so they can be added to the app via .qrc file
cmake_minimum_required(VERSION 3.5)
project(l10n LANGUAGES CXX)
find_package(Qt5 COMPONENTS Core LinguistTools REQUIRED)
# genearats ts and qm file searching recursively SRC_DIR
function(generate_translations CUSTOM_TARGET TS_DIR TS_FILES SRC_DIR)
set(UPADTE_TS_TARGET_NAME ${CUSTOM_TARGET}_ts)
set(UPADTE_QM_TARGET_NAME ${CUSTOM_TARGET}_qm)
add_custom_target(${UPADTE_TS_TARGET_NAME}
COMMAND ${Qt5_LUPDATE_EXECUTABLE} -recursive ${SRC_DIR} -ts ${TS_FILES}
WORKING_DIRECTORY ${TS_DIR})
add_custom_target(${UPADTE_QM_TARGET_NAME}
COMMAND ${Qt5_LRELEASE_EXECUTABLE} ${TS_FILES}
WORKING_DIRECTORY ${TS_DIR})
add_dependencies(${UPADTE_QM_TARGET_NAME} ${UPADTE_TS_TARGET_NAME} )
add_dependencies(${CUSTOM_TARGET} ${UPADTE_QM_TARGET_NAME})
endfunction()
add_executable(l10n main.cxx)
target_link_libraries(l10n Qt5::Core)
set(MY_TS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/translate)
set(MY_TS_FILES foo_en.ts foo_en.ts)
set(MY_SOURCE_LOOKUP_DIR ${CMAKE_CURRENT_SOURCE_DIR})
generate_translations(l10n "${MY_TS_DIR}" "${MY_TS_FILES}" "${MY_SOURCE_LOOKUP_DIR}")
can you use lupdate.exe, linguist.exe and lrelease.exe from qt/[qt_version]/[msvc|mingw|...]/bin/ ?
you can use it like that:
Usage:
lupdate [options] [project-file]
lupdate [options] [source-file|path]... -ts ts-files
Options:
-help Display this information and exit.
-noobsolete
Drop all obsolete strings.
-extensions [,]...
Process files with the given extensions only.
The extension list must be separated with commas, not with whitespace.
Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'.
-pluralonly
Only include plural form messages.
-silent
Do not explain what is being done.
-version
Display the version of lupdate and exit
so, [source-file|path] - is you option, like i think.
try to call it with list of source files names.