Using C/CPP, you can’t avoid dealing with all kinds of header files. The system library is ok, basically do not need to worry about, has been automatically preset into the header file list. The tricky part is using third-party libraries, where you need to manually specify the location of the header and library files. This article documents the setup for compiling manually in a terminal versus in some tools.
Compile manually in terminal using GCC /clang/makefile
GCC -i /include -c test.c -o test.o GCC test.o -l /libs -o test The number of header files and library files is relatively large. It would be rather cumbersome if we wrote them one by one manually. So, pkG-config was born
In short, PKG-config provides the library with the ability to compile and link flags.
PKG – config installation
brew install pkg-config
Copy the code
Pkg-config Common command
pkg-config --help
: View helppkg-config --list-all
: Lists all the libraries currently on the system that support PKG-configPKG - config -- cflags glib - 2.0
: Specifies a header filePKG - config - libs glib - 2.0
: Specifies the library file
Pkg-config also has other functions. You can see all available commands through pkg-config –help
Compile at the terminal using PKg-config
The most basic usage is simply to write pkG-config –cflags –libs glib-2.0 as one of the arguments to GCC.
# Note 'grave/tilde key, not single quotes
$gccC 'pkg-config --cflags --libs glib-2.0' -o mainCopy the code
Principle of PKG-config and custom location
Pkg-config uses a.pc file defined by a third-party library to locate header files and library files. For example, glib’s PC file looks like this:
The prefix = / usr/local/Cellar/glib / 2.66.7 libdir = ${prefix} / lib includedir = ${prefix} / include bindir = ${prefix} / bin glib_genmarshal=${bindir}/glib-genmarshal gobject_query=${bindir}/gobject-query glib_mkenums=${bindir}/glib-mkenums Name: GLib Description: C Utility Library Version: 2.66.7 Requires. Private: libpcre >= 8.31 - L ${libdir} - lglib - 2.0 - L/usr/local/opt/gettext/lib - lintl Libs. Private: -Wl,-framework,CoreFoundation -Wl,-framework,Carbon -Wl,-framework,Foundation -Wl,-framework,AppKit -liconv -lm Cflags: -i ${includedir} / glib - 2.0 - I ${libdir} / glib - 2.0 / include - I/usr/local/opt/gettext/includeCopy the code
Can see very clearly that glib in the/usr/local/Cellar/glib / 2.66.7 / lib/pkgconfig/glib – 2.0 PC has been defined in the relevant key information, such as Libs and Cflags. By default glib makes a soft link to its PC file in /usr/local/lib/pkgconfig
Some software may not automatically create soft links, or we may need to customize a.pc file. In this case, we need to add the following configuration to.zshrc:
/usr/local/lib/pkgconfig = /usr/local/lib/pkgconfig
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/zlib/lib/pkgconfig
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/ruby/lib/pkgconfig
export PKG_CONFIG_PATH
Copy the code
GCC main.c ‘pkg-config –cflags –libs zlib’ -o main pkg-config will automatically find the corresponding.pc file
Configure header files in VIm
Youcompleteme dependency header file path
The header file paths that yCM relies on for completion are:
-
C_INCLUDE_PATH/CPP_INCLUDE_PATH of the system
-
~/. Vimrc set path=***
-
The.ycm_extra_conf file defined in yCM
Ycm’s.ycm_extra_conf.py I usually define in.vimrc as a fixed configuration
# ~/.vimrc let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' "Default configuration file path Copy the code
In the ~/.ycm_extra_conf.py file, flags represents the configuration options we use, where /usr/local/include represents a hint to complete the Homebrew installed header file, or add a custom path if not enough
# ~/.ycm_extra_conf.py flags = [ '-Wall'.'-Wextra'.'-Werror'.'-fexceptions'.'-DNDEBUG'.'-std=c11'.'-x'.'c'.'-isystem'.'/usr/include'.'-isystem'.'/usr/local/include'.# Important, most of the headers installed via Homebrew are here '-isystem'.'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/.. /lib/c++/v1'.'-isystem'.'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include',]Copy the code
Of course, if each third-party library path needs to be added manually, it would be too cumbersome. We can simply import the system pkg-config output into flags as a path
# ~/.ycm_extra_conf.py Add header file path to YCM completion easily via pkg-config def pkg_config(pkg) : def not_whitespace(string) : return not (string == ' ' or string == '\n') output = subprocess.check_output(['pkg-config'.'--cflags', pkg]).decode().strip() return list(filter(not_whitespace, output.split(' '))) flags += pkg_config('glib-2.0') Copy the code
All of the above paths can play an auxiliary role in yCM completion.
The header file path on which ALE depends
Ale is a Lint tool that supports many languages. Ale is actually a collection of linters for different languages, so we can just choose one of them. For example, I chose Clangd as a LINter for C/CPP. Ale provides setup options for each linter, and Clangd is no exception:
# ~/.vimrc
/usr/local/lib/pkgconfig = /usr/local/lib/pkgconfig
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/zlib/lib/pkgconfig
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/ruby/lib/pkgconfig
export PKG_CONFIG_PATH
CPPFLAGS+=$(pkg-config --cflags glib-2.0 zlib ruby-3.0)
exportCPPFLAGS CFLAGS+=$(pkg-config -- CFLAGS glib-2.0 zlib ruby-3.0)export CFLAGS
LDFLAGS+="-I/usr/local/opt/openjdk/include"
LDFLAGS+=$(pkg-config --libs glib-2.0 zlib ruby-3.0)
export LDFLAGS
Copy the code
let g:ale_linters= {\'c': ['clangd'], and \'cpp': ['clangd'], and \'markdown': ['markdownlint'], and \}let g:ale_c_clangd_options = $CFLAGS
let g:ale_cpp_clangd_options = $CFLAGS
let g:ale_markdown_markdownlint_options='-c $HOME/.markdownlint.json'
Copy the code
Here I use CFLAGS in ~/.zshrc to export the custom header configuration, which can be defined in one place and used in multiple places
The path to the header file on which the compile run depends
Skywind3000 /asyncrun: skywind3000/asyncrun: skywind3000/asyncrun: skywind3000/asyncrun: skywind3000/asyncrun: skywind3000/asyncrun: skywind3000/asyncrun: skywind3000/asyncrun
map <F2> : call Run()<CR>
func Run()
exec 'w'
if &filetype= ='c'
exec 'AsyncRun! GCC 'pkg-config --cflags --libs glib-2.0' -wall -o2 "$(VIM_FILEPATH)" -o "$HOME/. Cache /build/C/$(VIM_FILENOEXT)" && "$HOME/.cache/build/C/$(VIM_FILENOEXT)"'
elseif &filetype= ='java'
exec 'AsyncRun! javac %; time java %<'
elseif &filetype= ='sh'
exec "AsyncRun! time bash %"
elseif &filetype= ='python'
exec 'AsyncRun! time python3 "%"'
endif
endfunc
Copy the code
So in the C file, just press
to execute immediately
Xcode configures header files and library files
TARGETS -> Build Settings -> Search Path -> Header Search Paths/Library Search Paths set the corresponding Header and Library file Paths
conclusion
There are different ways to configure header and library files, but all revolve around how to easily list the paths to header and library files for compiling links. Mastering this point, we can try to solve the problem according to this idea even when using other tools.
reference
- Principle and usage of PKg-config