i want to move from using CMake to Premake for my current project, but im usig vim and the YCM plugin which is really great for making my setup like an IDE. However, the plugin needs compilation flags file which is produced when running CMake. Is there something for Premake to generate a file like that as well?
Premake does not do this in its current state (alpha 13). If you have some insights as to what is necessary for getting it to work, the best thing to do would be to submit a ticket in the issue tracker.
I'm afraid, if your new build system does not generate that compilation flags file (yet), you'll need to maintain your own (hand-crafted) one. You can find an example at https://github.com/Valloric/ycmd/blob/0e999dbee209ea79a522259816ce3a68b7d6cddc/examples/.ycm_extra_conf.py.
I would advice to have (at least) one per project rather than one generic one in your $HOME.
Although I have to admit, that it would be beneficial to get it created and in sync with the actual build system, I don't find it too troublesome to maintain it manually. At the end of the day it only contains the C++ standard you want to use, a set of preprocessor symbols and a set of both system and user include directories.
Related
I'd like to build a small set of vimscript libraries, however, it seems that the only way to use them would be to load them all globally into vim.
Furthermore, it means that if i wanted to share a single script that depends on those, i'd have to share to them all, which sounds tiresome.
What i was hoping for is some common.js and webpack style approach to vimscript,
does such a thing exist. Something that:
Resolves dependencies
Allows for vimscript files to be "bundled" together into one file.
Everything that i found, winds up being a plugin manager, rather than a plugin build tool.
Do such things exist?
The situation so far, up to Vim 8.
There is no script isolation. When a script is loaded, it's globally. The script can hide variables and functions, but that's all.
Sharing/exporting a function is quite easy: we drop it in an autoload plugin, and we just have to use that function named dirrelatativeto_rtp#subdir#suddir...#scriptname#funcname(). If the script scriptname.vim is installed in dirrelatativeto_rtp/subdir/subdir somewhere in a directory registered in 'runtimepath', it'll get loaded automatically.
Regarding commands, abbreviations, mappings... they are meant to be defined in plugin files, or ftplugin files -- other approaches are possible when we want submodes. Also we cannot use them naively from an autoload plugin or when a script is being loaded -- we'll have to explicitly use :runtime to load the script where this command/mapping/... is defined (as we'd do an import in Python).
Yet, like with Python, scripts aren't installed automagically on our system. It's still up to us to trigger manually the installation of scripts.
We can decide to have library plugins and other plugins that depend on these libraries. But, we need either to tell the end-user everything that must be installed manually, or kindly tell him/her to stop using a plugin manager that don't understand dependencies.
This has been a personal rant of mine for years, the trendy plugin managers don't understand dependencies. There are so far only two plugin managers that do so:
Vim-Addon-Manager (aka VAM): it relies on a central repository (vim-pi) to install a plugin (and its dependencies) with just its name (e.g. :InstallAddon fugitive, :InstallAddon lh-cpp). Unfortunately the central repository is no longer maintained and we can't register new names. Fortunately, we can always install anything with :InstallAddon github:{N}/{repo}. Other functions are available for installing from the .vimrc.
and vim-flavor which is written in ruby, and which install plugins as Vim 8 packages.
Both have their own syntax to declare dependencies. Unlike VAM, we can specify constraints on plugin versions with vim-flavor.
Last thing, if we don't want to distribute all files, we can organize them as several "plugins". But beware of cyclic dependencies. And be kind to end users that are using these trendy plugins managers that don't understand dependencies as they'll need to explicitly install many "plugins"
Starting from Vim 9
We can start to isolate imported plugins in the sense that two plugins can define a function or a command with a same name. Again, this feature seems to mimic Python way of doing things.
However, I expect global stuff like autocommands to continue to operate globally. For instance: I don't see how we could have two template expander plugins running concurrently.
Vim 9 new scripting language won't change anything to the installation of plugins we depend on.
Disclaimer: It has been almost 2 decades now that I've been maintaining my plugins as a bunch of interdependent plugins, organized around a few library plugins, as I don't like to duplicate a same thing several times. In my rant about dependencies & co, I explore quickly other alternative approaches available to us.
Back to the bundling/packaging question (EDIT)
We have ways to package files together.
We can always manually define plugins: put files together in a directory tree, play with git and so on.
We can define tarballs.
We can also define vimballs. Vimballs are a quite old solution for installable archives: files are put in their right directory and documentation tags are produced. There are ways to produce vimballs. I continue to maintain scripts that help producing them for all my plugins. But in all honesty, this is not what people expect to have nowadays to install plugins. I just keep them around in case I release new versions of my plugins on vim.org.
In any case, neither of these solutions end up defining one single file we put somewhere in our ~/.vim/ directory. And I think we will never have something like that because:
Isolation is not perfect. Even with Vim 9 new scripting language: I don't see how we could correctly handle duplication of autocommands. If a same file, that defines autocommands, is duplicated in different versions in several distributed "plugins" I don't see how Vim could handle that correctly.
Vim expects different files in different places: ftplugins, plugins (the original meaning in vim context, not the set of files that could be installed together), syntax files, fold plugins, indent plugins, colorschemes, langmaps, and so on. Vim architecture does not expect everything in a single file.
For these reasons, I cannot see how we could have build systems that build single files ready to be distributed. It could work in some cases (pure collections of functions and "classes"), but not in the general case.
I am on the quest of creating a compile_commands.json database from my IAR .ewp project. This would allow me to use intelligent LSP autocompletion (ccls) and proper semantic highlighting (vim-lsp-cxx-highlight) from my vim setup.
I understand that I could manually create a CMake file with the same setup as in the .ewp project file, but unfortunately all my co-workers use the IAR IDE. I would risk missing some important project setup changes made by my co-workers and me failing to update the .ewp. It'd be great if I could automatically parse the .ewp file to CMake, and hence create the commands database.
Anybody knows of a clever way of doing this? If not, how would I go creating a tool that does exactly that? It appears that by undefining the Clang compiler defines one could make ccls use of the IAR code-base at full strenght.
Use -jsondb option in IAR
> iarbuild.exe example.ewp -jsondb debug -output compile_commands.json
I have a cmake project. I want to do the following easily
search the declaration, definition and references of any variable, function, etc. under the cursor, which may be declared in an external header file whose path is added using INCLUDE_DIRECTORIES in CMakeLists.txt
rename a variable, function, etc. that is declared in the project
How can I set this up?
You can try to use vim plugin cmake4vim in order to integrate CMake to Vim.
This plugin helps to work with cmake targets and allows to generate compilation database file (compile_commands.json). A lot of plugins use this file for code completion, jump to definition and etc. (for example YCM)
Also you can use vim lsp plugins (for example vim-lsp) these plugins use language servers for code completion, refactoring and another good features.
But CMake project integration (cmake cache generation, project compilation, etc.) and search the declaration, definition and etc are different tasks. And different plugins and tools solve these tasks.
You can tell Vim where to look for includes by adding entries to the path option. I don't have enough experience with Cmake to know how to pull paths from CMakeLists.txt, though.
See :help 'path'.
Assuming a properly set path, it is possible to use the built-in :dsearch and related commands to search for definitions across includes.
The define option has a prescriptive name but it could be used to find any specific pattern so you could alter it to match declarations, too, or really anything.
See :help include-search and :help 'define'.
Vim has no built-in concept of "reference". :isearch and friends should work for that but they will probably be too noisy.
Renaming is usually done with something like:
:grep foo paths
:cwindow
:cdo s/foo/bar/gc
YouCompleteMe will help you. It uses compilation_database.json, witch can be generated by cmake.
This plugin also provides autocompetion for many languages.
I use functions in vim and assign them to a hotkey.
https://developer.ibm.com/tutorials/l-vim-script-2/
it gives you more an IDE feel. but at the end of the day you get a bit more control.
I've defined a CMakeLists.txt file for my project which works correctly.
I use the CMake GUI for generating a Visual Studio Project, and I ask to build the binaries (CMAke cache and other stuff) in the folder Build which is in the same folder where CMakeLists.txt is.
I was able to specify where the executable and the libraries have to be created.
Is there a way to specify also where the Visual Studio Solution file has to be created? I would like to have it in the root directory, but at the same time I don't want to have also all the other files that CMake creates in the Build directory.
CMake creates the Project I defined in CMakeLists.txt but also two other projects: ALL_BUILD and ZERO_CHECK. What's their utility?
I was able to avoid the creation of ZERO_CHECK by using the command set_property(GLOBAL PROPERTY USE_FOLDERS On).
Is there a way for avoiding also the creation of ALL_BUILD?
It seems you only switched to CMake very recently, as exactly those questions also popped into my head when I first started using CMake. Let's address them in the order you posted them:
I use the CMake GUI for generating a Visual Studio Project, and I ask
to build the binaries (CMAke cache and other stuff) in the folder
Build which is in the same folder where CMakeLists.txt is.
Don't. Always do an out-of-source build with CMake. I know, it feels weird when you do it the first time, but trust me: Once you get used to it, you'll never want to go back.
Besides the fact that using source control becomes so much more convenient when code and build files are properly separated, this also allows to build separate distinct build configurations from the same source tree at the same time.
Is there a way to specify also where the Visual Studio Solution file has to be created?
You really shouldn't care.
I see why you do feel that you need full control over how the solution and project files get created, but you really don't. Simply specify the target for the solution as the origin of your out-of-source build and forget about all the other files that are generated. You don't need to worry, and you don't want to worry - this is exactly the kind of stuff that CMake is supposed to take care of for you.
Ask yourself: What would you gain if you could handpick the location of every project file? Nothing, because chances are, you will never touch them anyways. CMake is your sole master now...
CMake creates the Project I defined in CMakeLists.txt but also two
other projects: ALL_BUILD and ZERO_CHECK. What's their utility? I was
able to avoid the creation of ZERO_CHECK by using the command
set_property(GLOBAL PROPERTY USE_FOLDERS On). Is there a way for
avoiding also the creation of ALL_BUILD?
Again, you really shouldn't care. CMake defines a couple of dummy projects which are very useful for certain internal voodoo that you don't want to worry about. They look weird at first, but you'll get used to their sight faster than you think. Just don't try to throw them out, as it won't work properly.
If their sight really annoys you that much, consider moving them to a folder inside the solution so that you don't have to look at them all the time.
Bottom line: CMake feels different than a handcrafted VS solution in a couple of ways. This takes some getting used to, but is ultimately a much less painful experience than one might fear.
You don't always have a choice about what your environment requires. Visual Studio's GitHub integration requires that the solution file exists in source control and is at the root of the source tree. It's a documented limitation.
The best I was able to come up with is adding this bit to CMakeList.txt:
# The solution file isn't generated until after this script finishes,
# which means that:
# - it might not exist (if this is the first run)
# - you need to run cmake twice to ensure any new solution was copied
set(sln_binpath ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.sln)
if(EXISTS ${sln_binpath})
# Load solution file from bin-dir and change the relative references to
# project files so that the in memory copy is as if it had been built in
# the source dir.
file(RELATIVE_PATH prefix
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
file(READ ${sln_binpath} sln_content)
string(REGEX REPLACE
"\"([^\"]+).vcxproj\""
"\"${prefix}/\\1.vcxproj\""
sln_content
"${sln_content}")
# Compare the updated contents with the existing source path sln, if it
# exists and is the same we don't want to disturb VS by touching it.
set(sln_srcpath ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.sln)
set(old_content "")
if(EXISTS ${sln_srcpath})
file(READ ${sln_srcpath} old_content)
endif()
if(NOT old_content STREQUAL sln_content)
file(WRITE ${sln_srcpath} ${sln_content})
endif()
endif()
What would be helpful is if cmake had a way to run post generation scripts, but I couldn't find one.
Other ideas that didn't work out:
wrap cmake inside a script that does the same thing, but:
telling users to run a seperate script isn't simpler than saying to run cmake twice. Especially since needing to run cmake twice isn't a foreign concept.
put it in a pre-build step, but
building is common and changing the build is rare
changing the solution from builds inside the IDE makes it do... things
use add_subdirectory because that's suppose to finish first
it appeared to make the vcxproj's immediately, but not the sln until later, but I didn't try as hard because this adds a bunch of additional clutter I didn't want - so maybe this can be made to work
I come from a Java background, and the shop where I currently work refuses to use anything other than MS VC++ to build their legacy project. They don't appear to use any standards for setting up their build environment other than just building it using VS2005 and clicking the compile button.
I was wondering if there was anything closer to what Java had for instance:
A build tool like ANT or Maven
A directory structure that makes sense containing
src - Place for all my source files .c/.cpp/.h
lib - A place for any libraries that might be used in the project (.dll, .lib)
dist - A place for the output executable/distribution of the project
resources - A place for any images/sounds/text files that might be included in the project.
build.xml - Some sort of a build file (my guess would be something like ./configure or MAKEFILE)
Or am I asking too much from a C++ build environment? Is it just always as chaotic as the people in my shop make it out to be? I really have a hard time believing that considering the success of so many C++ projects on the internet.
It sounds like you have good intentions - coming form a non MSVC world I can see your points.
If I were in y our shoes I would definitely make a command line/automated build/build server.
You can use MSBuild for this - and hudson has a plugin for this. I usually have a "Build" directory near the root of the projects that contains scripts/etc that will call the appropriate MSBuild/.sln files.
The "makefiles" for Visual Studio are .sln and .vcproj files. You can call those with msbuild from the command line. You can also export a makefile (I think that is still an option) from within the IDE that you can run. I don;t recommend going that route though other than trying it out and seeing what is output - since that is what you are familiar with.
Both the vcproj and sln files are human readable - go through them - it will give you some useful information.
I would also agree that having a distributon directory is good - for building an installer/etc after the build. Copy all the needed binaries there - either in postbuild steps or in another script/etc.
Let us know what you end up doing.
I have one other piece of advice:
UPGRADE to VC/Dev studio 2008 or 2010. ASAP
MSVC does not impose any directory structure on you. There are some defaults, as mentioned above for the Debug and Release directories, for example, but even these can be overridden on a per-project basis. Use whatever directory structure makes sense to you.
Visual Studio does provide command line support if you don't want to use the IDE. See This MSDN Article for more information.
You can setup a proper build environment using Visual Studio (and for solutions with more than one project, you should), and there are a number of environment variables to use in the project configuration to set so that output files and intermediate files go to different folders than those defined by default.
In our large VS solution, we use e.g. obj/$(ProjectName)/$(ConfigurationName) as intermediate directory and bin/$(ConfigurationName) as output directory in all sub-projects.
All these things must be enforced by the user, and it seems that no single recommendation/best practice has evolved.
The standardized stuff:
The build tool: Visual Studio (doesn't need an extra product)
Build file: *.sln / *.vcproj (*.vbproj for Visual Basic, etc)
Directory structure: "Debug" and "Release" directories for the output binaries.
The rest isn't so much "chaotic" as "doesn't really matter". "Chaotic" suggests that it changes all the time, but in reality you just pick one for a project and stick with it. Companies may have internal standards across projects. It just doesn't matter enough to bother standardizing across companies. C++ is a complex language anyway; anyone with sufficient IQ to read C++ can deal with reasonable variation. The difference between \lib\ and \Library\ won't stop them.