How to change C++ include guards in CLion?
Asked Answered
R

4

14

When CLion creates a header file it adds include guard strings like this:

#ifndef PROJECTNAME_FILENAME_H
#define PROJECTNAME_FILENAME_H

/* ... code ... */

#endif //PROJECTNAME_FILENAME_H

But I want just FILENAME_H without the PROJECTNAME_ prefix. How to change it in CLion settings?

Retinoscope answered 21/4, 2016 at 11:5 Comment(7)
You should avoid using only FILENAME_H, it is not that rare to have multiple files with the same name in a project.Litigable
This wouldn't help in this case since the other header (with the same filename) would also use the include guards PROJECTNAME_FILENAME_HSkied
One alternative would be to use #pragma once instead of the #ifndef include guards. The template used for header file creation can be changed under Settings->Editor->File and Code Templates.Keynote
Some sources say that with #define compilation is faster. And #pragma once is not a part of pre-C++11 versions of standard. I don't believe ${PROJECT}_${FILE}_H is hardcoded in CLion.Retinoscope
@Kroll, what sources say that?Caban
@TamásSzelei: I remember GCC themselves saying something related (gcc.gnu.org/onlinedocs/cpp/Once-Only-Headers.html): "CPP optimizes even further. It remembers when a header file has a wrapper ‘#ifndef’. If a subsequent ‘#include’ specifies that header, and the macro in the ‘#ifndef’ is still defined, it does not bother to rescan the file at all."Arched
The pattern - once I "discovered" it some 15 or so years ago - I use is <FILENAME>_<EXT>_INCLUDED_<YYYYMMDD>. When I happen to write 2d/Vector.hh and 3d/Vector.hh on the same day, I spontaneously add something additional, like wall time (VECTOR_HH_INCLUDED_20181003_1953) or folder (MATH_2D_VECTOR_HH_INCLUDED_20181003). Of course it's still not perfect (some library may also come with VECTOR_HH_INCLUDED_20181003), but in reality, the vector-example is the only incident that happened to me. The INCLUDED part is just for aesthetics.Arched
H
9

Bit late to this question, but I've got a slightly more involved solution that'll handle this without the need for manual post-processing regardless of file extension:

  1. Head into your File and Code Templates - The other answers already detail how to do this.
  2. In the File and Code Templates settings page, change to the Includes tab.
  3. Click the + to create a new Include template. Name it something like IncludeGuard and set the Extension to h.
  4. Input the following for the contents. Make sure you don't include any blank lines before or after.
#macro( includeGuard $filename $ext )
#set( $ucfull = ${filename.toUpperCase().replace('-', '_')} )
#set( $extidx = ${ucfull.lastIndexOf(".")} )
#set( $extstart = $extidx + 1 )
#if( $extidx > -1 )
#set( $ucname = ${ucfull.substring(0,$extidx)} )
#set( $ucext = ${ucfull.substring($extstart)} )
#else
#set( $ucname = $!{ucfull} )
#set( $ucext = ${ext.toUpperCase()} )
#end
${ucname}_${ucext}##
#end##
  1. Change back to the Files tab, and find the C Header File or C++ Class Header file depending on which language you're looking to update.
  2. Change the contents of this file template to:
#parse("IncludeGuard.h")##
#set( $blank = "" )
#[[#ifndef]]# #includeGuard(${NAME} "h")${blank}
#[[#define]]# #includeGuard(${NAME} "h")${blank}

// ...

#[[#endif]]# // #includeGuard(${NAME} "h")

If everything works as intended, attempting to create a C Header File using the name test-include-guard or test-include-guard.h should both result in the following:

#ifndef TEST_INCLUDE_GUARD_H
#define TEST_INCLUDE_GUARD_H

// ...

#endif /* TEST_INCLUDE_GUARD_H */

Few notes:

  • If you need to change the file extension, change the includeGuard(${NAME} "h") parts to use whatever extension you want for the second parameter. The template will attempt to parse the file extension from ${NAME}, but ${NAME} only contains the file extension if you explicitly enter it into the new filename dialog.
  • The current state of whitespace handling in the Velocity templates used by CLion is a shit show, so you'll need to work around this as I did if you decide to further customize the templates. General guidelines:
    • If you're experiencing undesired linebreaks, you'll want to try adding a terminating line comment ## to the ends of lines before it.
    • If you find yourself in the oppostie scenario, (missing an expected linebreak) you can work around this with the #set( $blank = "" ) strategy I utilized above.
  • Most of the IntelliJ-based IDEs seem to cache the compilation of Include templates the first time they get passed into #parse(). If you make changes to an Include template after this point, you'll usually need to use the File > Invalidate Caches/Restart menu command before the changes propagate.
Holozoic answered 23/4, 2018 at 0:10 Comment(0)
L
8
  1. Settings->Editor->File and Code Templates->Files
  2. change ${INCLUDE_GUARD} into _${NAME}_H_

For example, if your file name is: clion.h, then _${NAME}_H_ is rendered as _clion_H_, because ${NAME} is rendered as the filename (without extension).

Labradorite answered 15/6, 2016 at 13:4 Comment(0)
M
1

File | Settings | Editor | File and Code Templates for Windows and Linux

CLion | Preferences | Editor | File and Code Templates for OS X

#[[#ifndef]]# BASE_${HEADER_FILENAME}
#[[#define]]# BASE_${HEADER_FILENAME}


#[[#endif]]# //BASE_${HEADER_FILENAME}

>

#ifndef BASE_test_h
#define BASE_test_h

#endif //BASE_test_h

select BASE_test_h and press CTRL + SHIFT + U to upper case

Mascarenas answered 27/11, 2016 at 3:41 Comment(0)
S
1

According to the latest doc (2019.3, but it may work in earlier versions, too) you can navigate to the Naming Convention tab under Settings / Preferences | Editor | Code Style | C/C++.

There you'll find a field that allows you to easily change the header guard pattern. No need to add custom templates anymore.

enter image description here

Selmner answered 14/1, 2020 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.