Sarcasm / irony-mode

A C/C++ minor mode for Emacs powered by libclang
GNU General Public License v3.0
906 stars 99 forks source link

How to setup irony to use MSVC compile options? #280

Open mambolevis opened 8 years ago

mambolevis commented 8 years ago

Hi Guillaume, After building the irony-server.exe using cmake Visual Studio 14 2015 Win64 and setting up (company, yasnippet, irony and company-irony), I tested it in a very basic project and the completion using system headers is working fast and properly. In order to continue the setup of the C++ environment in emacs (windows), I would like to listen your advice/recommendation in the following points:

  1. How can I verify were the system headers are taken from? I don't know (even that it is working) where the headers are taken. I need to be sure that irony search msvs headers.
  2. I tried to setup project includes using .clang_complete but it didn't work. How can I do that? -I/inc
  3. I would like to have code navigation using either (ggtags, helm-gtags, rtags or company-gtags) the point is that I don't know which can be used on windows?

Bellow can you see, project structure, main.cpp and an extract of the init.el file with my currently setup of (company, yasnippet, irony and company-irony).

Thanks Levis

------project structure basic_project_root -> inc ----> std_lib_facilities.h -> main.cpp -> emacs_Shell.bat -> .clang_complete

// main.cpp

include

include

include "std_lib_facilities.h"

int main(int argc, char *argv[]) { std::string s1; s1 = "hello world"; s1.append(" desde kassel"); std::cout << "s1 = " << s1 << "\n"; //------------- keep_window_open(); return 0; }

;;; init.el (use-package company :ensure t :config (global-company-mode))

(use-package yasnippet :ensure t :init (progn (setq yas-verbosity 3) (yas-global-mode 1)) :config (yas-reload-all))

(use-package irony :commands irony-mode :init (setq w32-pipe-read-delay 0) (add-hook 'c-mode-hook 'irony-mode) (add-hook 'c++-mode-hook 'irony-mode) ;;(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options) :config ;(setq company-minimum-prefix-length 0) (use-package flycheck-irony :config (add-hook 'flycheck-mode-hook 'flycheck-irony-setup)))

(use-package company-irony :config (add-to-list 'company-backends 'company-irony))

;; Add yasnippet support for all company backends ;; https://github.com/syl20bnr/spacemacs/pull/179 (defvar company-mode/enable-yas t "Enable yasnippet for all backends.")

(defun company-mode/backend-with-yas (backend) "Company and yasnippet with BACKEND as argumet." (if (or (not company-mode/enable-yas) (and (listp backend) (member 'company-yasnippet backend))) backend (append (if (consp backend) backend (list backend)) '(:with company-yasnippet))))

(setq company-backends (mapcar #'company-mode/backend-with-yas company-backends))

mambolevis commented 8 years ago

@Sarcasm Hi, bellow the tests:

Could you re-test 1.3 with these 2 changes? By the way -I/inc should not work, the one of interest is -Iinc.

-target
i686-pc-windows-msvc
-fms-extensions
-fms-compatibility
-fms-compatibility-version=19
-fdelayed-template-parsing
-Iinc
-working-directory
c:/home/projects/basic_project/
--driver-mode=cl

The result is the same: If I change (1.2 setup) the flag -I../inc by -Iinc the completion did not find the include file.

Regarding

2.2 If I add--driver-mode=clthe compilation failed: Interesting (and disappointing) results.

Yes, It was the motivator to divide the test report in three parts. I noticed that completionand compilationflags are related but don't work necessarily identically. It should be good idea if @3246251196 make the same test to validate the results.

Muchas gracias, saludos.

3246251196 commented 8 years ago

@Sarcasm

I am not sure if this is an irony thing, but I thought I would bring it up here. It is not uncommon for projects to be in C++ and use cpp files, but use h files (that ought to be hpp files).

Clang should be able to deal with the situation where you want a .h file to be compiled as if a .hpp file. However, it seems not be obeying this...

execute: Command{action=Command::Complete, file='d:/somfile.h', line=105, column=1, flags=['-x', 'c++', '-working-directory',

I have truncated the rest. However, -x c++ should tell clang that this is a C++ file. However, I get the following errors:

:/somefile.h:20:1: error: unknown type name 'namespace'
d:/somfile:20:21: error: expected ';' after top level declarator

This is because it is being treated as C language. If I rename the file then there is not a problem. But, the -x flag should work.

Have you ever came across this before? Should I report a bug?

Thank you.

Sarcasm commented 8 years ago

I have not seen this, irony-server header files use this naming and no issue for me.

Yes if it's a bug you should report it but first try to reproduce it with a clang tool, people may not want to build irony-server.

Irony-server is basically:

clang++.exe -fsyntax-only <args...>
3246251196 commented 8 years ago

I have not seen this, irony-server header files use this naming and no issue for me.

Yes if it's a bug you should report it but first try to reproduce it with a clang tool, people may not want to build irony-server.

Irony-server is basically:

clang++.exe -fsyntax-only

I have tested a suspected cause. The infamous --driver-mode=cl causes the issue. It is a bit of a shame, because I now cannot use the MSVC flags verbatim. I now have to remove all of them that are not D/I flags.

So, for example I wanted to have:

-target
i686-pc-windows-msvc
-fms-extensions
-fms-compatibility
-fms-compatibility-version=19
-fdelayed-template-parsing
-ferror-limit=0
--driver-mode=cl
/MP
/GS
/analyze-
/W4
/wd"4250"
/wd"4512"
/wd"4100"
/wd"4592"
/Zc:wchar_t
/ID:\development\External\boost_1_60_0
/ID:\development\External\xerces-c-3.1.2\src
/DLOG_CLI_TO_STDOUT=1

And this has changed to:

-target
i686-pc-windows-msvc
-fms-extensions
-fms-compatibility
-fms-compatibility-version=19
-fdelayed-template-parsing
-ferror-limit=0
-ID:/development/External/boost_1_60_0
-ID:/development/External/xerces-c-3.1.2/src
-DLOG_CLI_TO_STDOUT=1

Things that I do not know how to convert to cl-style options I have merely removed which I would prefer not to do. However, so far this works.

It would be nice if someone could test this out on their windows machine.

This does seem to back up the theory that --driver-mode=cl messes a few things up.

Cheers.

3246251196 commented 8 years ago
I have not seen this, irony-server header files use this naming and no issue for me.

Yes if it's a bug you should report it but first try to reproduce it with a clang tool, people may not want to build irony-server.

Irony-server is basically:

clang++.exe -fsyntax-only

I have tested a suspected cause. The infamous --driver-mode=cl causes the issue. It is a bit of a shame, because I now cannot use the MSVC flags verbatim. I now have to remove all of them that are not D/I flags.

So, for example I wanted to have:

-target i686-pc-windows-msvc -fms-extensions -fms-compatibility -fms-compatibility-version=19 -fdelayed-template-parsing -ferror-limit=0 --driver-mode=cl /MP /GS /analyze- /W4 /wd"4250" /wd"4512" /wd"4100" /wd"4592" /Zc:wchar_t /ID:\development\External\boost_1_60_0 /ID:\development\External\xerces-c-3.1.2\src /DLOG_CLI_TO_STDOUT=1

And this has changed to:

-target i686-pc-windows-msvc -fms-extensions -fms-compatibility -fms-compatibility-version=19 -fdelayed-template-parsing -ferror-limit=0 -ID:/development/External/boost_1_60_0 -ID:/development/External/xerces-c-3.1.2/src -DLOG_CLI_TO_STDOUT=1

Things that I do not know how to convert to cl-style options I have merely removed which I would prefer not to do. However, so far this works.

It would be nice if someone could test this out on their windows machine.

This does seem to back up the theory that --driver-mode=cl messes a few things up.

Cheers.

Okay, problem solved and with some very interesting and important findings.

I looked at cl.exe (MSVC compiler options). It is no good provided -x c++ - you MUST also supply the corresponding cl option (which indicates that the source file(s) should be interpreted as c++ code) in cl mode. In addition, clang will only allow one variant of the option (the options allow you to do /TP or /Tp - clang will only accept the lower case letter one. And, if that is not enough: the only way I can get this to work is to apply the option at the bottom of the .clang_complete file. Immediately after --driver-mode=cl will not work.

In summary, --driver-mode=cl is usable - but you must also apply the cl.exe option of \Tp (and specifically that one) at the bottom of the .clang_complete file. This also leaves me to believe that the other options I have in the .clang_complete file should be lower cases where possible.

-target
i686-pc-windows-msvc
-fms-extensions
-fms-compatibility
-fms-compatibility-version=19
-fdelayed-template-parsing
-ferror-limit=0
--driver-mode=cl
/MP
/GS
/analyze-
/W4
/wd"4250"
/wd"4512"
/wd"4100"
/wd"4592"
/Zc:wchar_t
/ID:\development\External\boost_1_60_0
/ID:\development\External\xerces-c-3.1.2\src
/DLOG_CLI_TO_STDOUT=1

Now works iff we append /Tp at the end such that we have:

-target
i686-pc-windows-msvc
-fms-extensions
-fms-compatibility
-fms-compatibility-version=19
-fdelayed-template-parsing
-ferror-limit=0
--driver-mode=cl
/MP
/GS
/analyze-
/W4
/wd"4250"
/wd"4512"
/wd"4100"
/wd"4592"
/Zc:wchar_t
/ID:\development\External\boost_1_60_0
/ID:\development\External\xerces-c-3.1.2\src
/DLOG_CLI_TO_STDOUT=1
/Tp

This is only relevant where you are using .h files that are really c++ files.

Sarcasm commented 8 years ago

I think your wd options are broken:

You should not have the quotes around them:

/wd"4250" -> /wd4250
3246251196 commented 8 years ago

I think your wd options are broken:

You should not have the quotes around them:

/wd"4250" -> /wd4250

Okay, I will change those, and downcase all the others where I can. For example /MP to /Mp (if I find there is such a variant; I have not yet checked).

I have added this knowledge to the WIKI.

Sarcasm commented 8 years ago

Regarding /Tp, I think irony will have to handle it at some point. Once we know what to do with /Tp, -working-directory and such we could automate this in irony-mode.

Congee commented 7 years ago

Currently, clang-4.0.0 doesn't link on windows. You have to compile and link separately. i.e. clang++ test.cpp -c link.exe -defaultlib:libcmt tset.o

3246251196 commented 6 years ago

@mambolevis

Hello, are you the one who suggested applying a patch to the clang which sped completion up? I am trying to remember where those patch files are.

Thanks.

3246251196 commented 6 years ago

Actually I have found it:

Index: lib/Support/MemoryBuffer.cpp
===================================================================
--- lib/Support/MemoryBuffer.cpp        (revision 320584)
+++ lib/Support/MemoryBuffer.cpp        (working copy)
@@ -284,6 +284,9 @@
                           bool RequiresNullTerminator,
                           int PageSize,
                           bool IsVolatile) {
+       // yaruopooner patch applied, rjd:
+       return false;
+
   // mmap may leave the buffer without null terminator if the file size changed
   // by the time the last page is mapped in, so avoid it if the file size is
   // likely to change.
mambolevis commented 6 years ago

@3246251196 Hi, yes I referenced it and used it long time before migrating to clang version 5.0.0 .

I stopped to using it since my latest build of irony-server 1.2.0 using clang version 5.0.0. Irony performs in general very fast. I have noticed that the completion performance decreases a bit when the completion is in the include files.