相信目前使用clang+llvm大有人在,我的系统ubuntu18.04前段时间刚安装了不少软件,习惯性的也会装上gcc/g++和clang/clang++,关于如何在两个编译器之间切换这里不再赘述,可能参考下面的链接:Switching between GCC and Clang/LLVM using CMake
写这个贴子是因为clang/clang++在网上大都没有一个完整的例子,大部分讲完clang就完事了,后面的链接部分语焉不详,所以这里给出一个完整的hello-world记录。
源码main.c
#include
int main() {
printf("Hello World.\n");
return 0;
}
CMakeLists.txt (参考:https://releases.llvm.org/5.0.0/docs/CMake.html ) (参考:https://llvm.org/docs/CMake.html)
cmake_minimum_required(VERSION 3.7.1)
project(hello-world)
find_package(LLVM REQUIRED CONFIG)
set(SOURCE_FILES main.c)
message(STATUS "This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
# Set your project compile flags.
# E.g. if using the C++ header files
# you will need to enable C++11 support
# for your compiler.
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
# Now build our tools
add_executable(hello-world ${SOURCE_FILES})
# Find the libraries that correspond to the LLVM components
# that we wish to use
llvm_map_components_to_libnames(llvm_libs support core irreader)
# Link against LLVM libraries
target_link_libraries(hello-world ${llvm_libs})
linux.toolchain.cmake
cmake_minimum_required( VERSION 2.6.3 )
set(CMAKE_SYSTEM_NAME Linux )
SET (CMAKE_C_COMPILER "/usr/bin/clang")
SET (CMAKE_C_FLAGS "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
SET (CMAKE_CXX_FLAGS "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_AR "/usr/bin/llvm-ar")
SET (CMAKE_LINKER "/usr/bin/llvm-ld")
SET (CMAKE_NM "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")
编译生成
这个其实就两条命令: $ cmake -DCMAKE_TOOLCHAIN_FILE=./linux.toolchain.cmake . $ make VERBOSE=1 VERBOSE是因为要输出更多的信息(毕竟是在学习嘛),可以看到链接的详细情况。
$ cmake -DCMAKE_TOOLCHAIN_FILE=./linux.toolchain.cmake .
-- The C compiler identification is Clang 6.0.0
-- The CXX compiler identification is Clang 6.0.0
-- Check for working C compiler: /usr/bin/clang
-- Check for working C compiler: /usr/bin/clang -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/clang++
-- Check for working CXX compiler: /usr/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- This is BINARY dir /home/matthew/devc/cmake/hello-world
-- This is SOURCE dir /home/matthew/devc/cmake/hello-world
-- Found LLVM 6.0.0
-- Using LLVMConfig.cmake in: /usr/lib/llvm-6.0/cmake
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matthew/devc/cmake/hello-world
$ make VERBOSE=1
/usr/bin/cmake -H/home/matthew/devc/cmake/hello-world -B/home/matthew/devc/cmake/hello-world --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/matthew/devc/cmake/hello-world/CMakeFiles /home/matthew/devc/cmake/hello-world/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: 进入目录“/home/matthew/devc/cmake/hello-world”
make -f CMakeFiles/hello-world.dir/build.make CMakeFiles/hello-world.dir/depend
make[2]: 进入目录“/home/matthew/devc/cmake/hello-world”
cd /home/matthew/devc/cmake/hello-world && /usr/bin/cmake -E cmake_depends "Unix Makefiles"
/home/matthew/devc/cmake/hello-world /home/matthew/devc/cmake/hello-world
/home/matthew/devc/cmake/hello-world /home/matthew/devc/cmake/hello-world
/home/matthew/devc/cmake/hello-world/CMakeFiles/hello-world.dir/DependInfo.cmake --color=
make[2]: 离开目录“/home/matthew/devc/cmake/hello-world”
make -f CMakeFiles/hello-world.dir/build.make CMakeFiles/hello-world.dir/build
make[2]: 进入目录“/home/matthew/devc/cmake/hello-world”
[ 50%] Linking CXX executable hello-world
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello-world.dir/link.txt --verbose=1
/usr/bin/clang++ CMakeFiles/hello-world.dir/main.c.o -o hello-world
/usr/lib/llvm-6.0/lib/libLLVMSupport.a /usr/lib/llvm-6.0/lib/libLLVMCore.a
/usr/lib/llvm-6.0/lib/libLLVMIRReader.a /usr/lib/llvm-6.0/lib/libLLVMAsmParser.a
/usr/lib/llvm-6.0/lib/libLLVMBitReader.a /usr/lib/llvm-6.0/lib/libLLVMCore.a
/usr/lib/llvm-6.0/lib/libLLVMBinaryFormat.a /usr/lib/llvm-6.0/lib/libLLVMSupport.a
-lz -lrt -ldl -ltinfo -lpthread -lm /usr/lib/llvm-6.0/lib/libLLVMDemangle.a
make[2]: 离开目录“/home/matthew/devc/cmake/hello-world”
[100%] Built target hello-world
make[1]: 离开目录“/home/matthew/devc/cmake/hello-world”
/usr/bin/cmake -E cmake_progress_start /home/matthew/devc/cmake/hello-world/CMakeFiles 0
注意,如果不在当前目录下,则需要根据实际情况设置目录,如
export CURRENT_SCRIPT_DIR=/home/matthew/devc/cmake/hello-world
cmake -DCMAKE_TOOLCHAIN_FILE=${CURRENT_SCRIPT_DIR}/linux.toolchain.cmake .
关于LLVM宏定义
LLVM相关的宏定义都在文件LLVMConfig.cmake中,一般情况下默认的路径如下所示 /usr/lib/llvm-6.0/cmake/LLVMConfig.cmake
如果你仔细阅读一下就会发现,LLVM_INCLUDE_DIRS和LLVM_INCLUDE_DIR是完全一样的,如下, set(LLVM_INSTALL_PREFIX "/usr/lib/llvm-6.0") ...... set(LLVM_INCLUDE_DIRS "${LLVM_INSTALL_PREFIX}/include") set(LLVM_LIBRARY_DIRS "${LLVM_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}") # These variables are duplicated, but they must match the LLVM variables of the # same name. The variables ending in "S" could some day become lists, and are # preserved for convention and compatibility. set(LLVM_INCLUDE_DIR "${LLVM_INSTALL_PREFIX}/include") set(LLVM_LIBRARY_DIR "${LLVM_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}")
参考资料下面是一些写得比较好的贴子或文档网址,记录一下,https://blog.csdn.net/dashuniuniu/article/details/50385528https://www.ibm.com/developerworks/cn/opensource/os-cn-clang/https://llvm.org/pubs/