Skip to content

Commit feaf6f9

Browse files
committed
Add an option to build clang from source code and more.
- new -DBUILD_LLVM cmake option to download and build LLVM and Clang when building wrapit - use above option for macOS CI as clang 13 is no more available from homebrew - remove test with julia-head, because it often needs a libcxxwrap_julia_jll that is not registered. - remove from test/runtest.jl use of --fresh cmake option, not supported in older cmake releases and improved cleanup before compilation by deleting the full build directory if it already exists.
1 parent 2c86cf3 commit feaf6f9

File tree

4 files changed

+197
-109
lines changed

4 files changed

+197
-109
lines changed

.github/workflows/test-linux.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ jobs:
1818
matrix:
1919
version:
2020
- '1.10'
21-
- 'nightly'
2221
os:
23-
- ubuntu-latest
22+
# - ubuntu-latest
23+
- ubuntu-22.04
2424
# - macOS-latest
2525
arch:
2626
- x64
2727
steps:
2828
- uses: actions/checkout@v3
2929
with:
3030
fetch-depth: 0
31-
- name: Install liclang
31+
- name: Install libclang
3232
run: |
3333
if [ "$RUNNER_OS" = Linux ]; then
3434
sudo apt-get install clang-13 libclang-13-dev

.github/workflows/test-macos.yml

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,29 @@ jobs:
1818
matrix:
1919
version:
2020
- '1.10'
21-
- 'nightly'
2221
os:
2322
# - ubuntu-latest
24-
- macOS-latest
23+
# - macOS-latest
24+
- macos-13
2525
arch:
2626
- x64
2727
steps:
2828
- uses: actions/checkout@v3
2929
with:
3030
fetch-depth: 0
31-
- name: Install liclang
31+
- name: Install libclang
3232
run: |
3333
if [ "$RUNNER_OS" = Linux ]; then
3434
sudo apt-get install clang-13 libclang-13-dev
35-
else #MacOS
36-
brew install llvm@13
35+
#else #MacOS
36+
# #brew install llvm@13 #llvm@13 no more supported by brew
37+
# wget "https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-13.0.1.tar.gz"
38+
# tar xzf llvmorg-13.0.1.tar.gz
39+
# rm llvmorg-13.0.1.tar.gz
40+
# export CMAKE_INSTALL_MODE=SYMLINK #use symlinks to reduce disk space usage
41+
# cmake -S llvm-project-llvmorg-13.0.1/llvm -B llvm-build -DCMAKE_INSTALL_PREFIX=`pwd`/clang-13 -DLLVM_ENABLE_PROJECTS="clang" -DBUILD_SHARED_LIBS=on -DLLVM_BUILD_LLVM_DYLIB=on -DCMAKE_BUILD_TYPE=Release
42+
# cmake --build llvm-build --verbose -j `sysctl -n hw.logicalcpu`
43+
# cmake --install llvm-build
3744
fi
3845
- uses: julia-actions/setup-julia@latest
3946
with:
@@ -49,13 +56,13 @@ jobs:
4956
rm -f /opt/hostedtoolcache/julia/1.6*/x64/lib/julia/libstdc++.so.6
5057
fi
5158
if [ "$RUNNER_OS" = Linux ]; then
52-
cmake -DClang_DIR=/usr/lib/llvm-13/lib/cmake/clang -B build -S .
53-
else #MacOS
54-
#cmake -DClang_DIR=/usr/local/Cellar/llvm@13/13.0.1_2/lib/cmake/clang/ -B build -S .
55-
echo ls /opt/homebrew/opt/llvm@13/lib/cmake/clang
56-
ls /opt/homebrew/opt/llvm@13/lib/cmake/clang
57-
cmake -DClang_DIR=/opt/homebrew/opt/llvm@13/lib/cmake/clang -B build -S .
59+
cmake -DClang_DIR=/usr/lib/llvm-13/lib/cmake/clang -DCMAKE_INSTALL_PREFIX="$PWD" -B build -S .
60+
cmake --build build --verbose -j `nproc`
61+
else
62+
cmake -DBUILD_LLVM=ON -DCMAKE_INSTALL_PREFIX="$PWD" -B build -S .
63+
cmake --build build --verbose -j `sysctl -n hw.logicalcpu`
5864
fi
59-
cmake --build build --verbose -j `nproc`
60-
PATH="`pwd`/build:$PATH"
65+
cmake --install build
66+
PATH="$PATH:$PWD/bin"
67+
export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"
6168
cd test && ./runtests.jl

CMakeLists.txt

Lines changed: 167 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -17,125 +17,204 @@ FetchContent_Declare(
1717
GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git
1818
GIT_TAG v3.0.0
1919
)
20+
21+
if(BUILD_LLVM) #in this mode llvm and clang codes are downloaded
22+
FetchContent_Declare(llvm
23+
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/llvm
24+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
25+
URL https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/llvm-13.0.1.src.tar.xz
26+
)
27+
FetchContent_GetProperties(llvm)
28+
if(NOT llvm_POPULATED)
29+
FetchContent_Populate(llvm)
30+
endif()
31+
32+
FetchContent_Declare(clang
33+
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/llvm/tools/clang
34+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
35+
URL https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/clang-13.0.1.src.tar.xz
36+
)
37+
FetchContent_GetProperties(clang)
38+
if(NOT clang_POPULATED)
39+
FetchContent_Populate(clang)
40+
endif()
41+
endif()
42+
2043
FetchContent_MakeAvailable(cxxopts)
2144

22-
# CLANG_JLL is used by Binary Builder
23-
# For building the package stand-alone it is not used
24-
if (NOT CLANG_JLL)
45+
project(MyProject)
46+
47+
# Option to enable LLVM/Clang download and build
48+
option(BUILD_LLVM "Download and build LLVM/Clang" OFF)
49+
50+
if(BUILD_LLVM)
51+
52+
function(add_llvm)
53+
set(CMAKE_BUILD_TYPE Release) #applies only for LLVM as defined in the function
54+
set(LLVM_BUILD_LLVM_DYLIB ON)
55+
set(LLVM_BUILD_TOOLS OFF)
56+
57+
set(LLVM_TARGETS_TO_BUILD host)
58+
59+
# Define a couple of LLVM cache variables of LLVM before adding the subdirectory
60+
# in order to choose the default values.
61+
set(LLVM_TARGETS_TO_BUILD ${LLVM_TARGETS_TO_BUILD_} CACHE STRING "Semicolon-separated list of experimental targets to build.")
62+
63+
set(CLANG_RESOURCE_DIR ${CMAKE_INSTALL_PREFIX}/lib/clang/13.0.1 CACHE STRING
64+
"Clang resource directory as returned by clang -print-resource-dir")
65+
66+
add_subdirectory(${llvm_SOURCE_DIR} ${llvm_BINARY_DIR})
67+
endfunction()
68+
69+
add_llvm()
70+
71+
# include_directories(${llvm_SOURCE_DIR}/include
72+
# ${clang_SOURCE_DIR}/include
73+
# ${llvm_BINARY_DIR}/tools/clang/include
74+
# ${llvm_BINARY_DIR}/include)
75+
76+
elseif (NOT CLANG_JLL)
2577

26-
find_package(Clang REQUIRED CONFIG)
27-
find_package(LLVM REQUIRED CONFIG)
28-
include_directories(${CLANG_INCLUDE_DIRS})
78+
find_package(Clang REQUIRED CONFIG)
79+
find_package(LLVM REQUIRED CONFIG)
80+
include_directories(${CLANG_INCLUDE_DIRS})
2981

30-
execute_process(COMMAND "${LLVM_TOOLS_BINARY_DIR}/clang" -print-resource-dir
82+
execute_process(COMMAND "${LLVM_TOOLS_BINARY_DIR}/clang" -print-resource-dir
3183
OUTPUT_VARIABLE CLANG_RESOURCE_DIR_DISCOVERED_PATH
3284
OUTPUT_STRIP_TRAILING_WHITESPACE)
33-
85+
3486
set(CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR_DISCOVERED_PATH}" CACHE
3587
FILEPATH "Clang resource directory as returned by clang -print-resource-dir")
3688

3789
if("${CLANG_RESOURCE_DIR}" STREQUAL "")
38-
message(FATAL_ERROR "CLANG_RESOURCE_DIR needs to be set to the Clang resource directory (see clang -print-resource-directory). This path is used at runtime by the wrapit executable.")
90+
message(FATAL_ERROR "CLANG_RESOURCE_DIR needs to be set to the Clang resource directory (see clang -print-resource-directory). This path is used at runtime by the wrapit executable.")
3991
else()
40-
if(NOT IS_DIRECTORY "${CLANG_RESOURCE_DIR}")
41-
message(WARNING "CLANG_RESOURCE_DIR value, " "${CLANG_RESOURCE_DIR}" ", does not point to an existing directory.")
42-
endif()
92+
if(NOT IS_DIRECTORY "${CLANG_RESOURCE_DIR}")
93+
message(WARNING "CLANG_RESOURCE_DIR value, " "${CLANG_RESOURCE_DIR}" ", does not point to an existing directory.")
94+
endif()
4395
endif()
4496

4597
else() # Using Clang_jll
46-
# find_package(Clang) leads to errors with Clang_jll
47-
# due to inconsitency in the lists of expected and installed files
48-
49-
set(CLANG_PREFIX "" CACHE FILEPATH "Root path of libclang that contains lib/libclang.so.")
50-
if("${CLANG_PREFIX}" STREQUAL "")
51-
find_library(LIBCLANG_PATH_ clang REQUIRED NOCACHE)
52-
get_filename_component(CLANG_PREFIX "${LIBCLANG_PATH_}" DIRECTORY)
53-
get_filename_component(CLANG_PREFIX "${CLANG_PREFIX}" DIRECTORY)
54-
unset(LIBCLANG_PATH_)
55-
message(STATUS "CLANG_PREFIX: ${CLANG_PREFIX}")
56-
endif()
57-
include_directories("${CLANG_PREFIX}/include")
58-
59-
set(CLANG_RESOURCE_DIR "" CACHE STRING
60-
"Clang resource directory as returned by clang -print-resource-dir")
61-
if("${CLANG_RESOURCE_DIR}" STREQUAL "")
62-
message("Searching clang resource directory in " "${CLANG_PREFIX}/lib/clang")
63-
file(GLOB CLANG_RESOURCE_DIR_ "${CLANG_PREFIX}/lib/clang/*/include/stddef.h")
64-
if("${CLANG_RESOURCE_DIR_}" STREQUAL "")
65-
message(FATAL_ERROR "Failed to find Clang resource directory")
66-
else()
67-
list(GET CLANG_RESOURCE_DIR_ 0 CLANG_RESOURCE_DIR)
68-
unset(CLANG_RESOURCE_DIR_)
69-
get_filename_component(CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" DIRECTORY)
70-
get_filename_component(CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" DIRECTORY)
71-
message(STATUS "CLANG_RESOURCE_DIR: ${CLANG_RESOURCE_DIR}")
72-
endif()
73-
endif()
74-
75-
set(SHARED_LIBS libclang clang-cpp LLVM)
76-
foreach(shared_lib IN LISTS SHARED_LIBS)
77-
add_library(${shared_lib} SHARED IMPORTED)
78-
set(lib_path "${CLANG_PREFIX}/lib/lib${shared_lib}${CMAKE_SHARED_LIBRARY_SUFFIX}")
79-
string(REPLACE liblib lib lib_path ${lib_path})
80-
set_property(TARGET ${shared_lib} PROPERTY
81-
IMPORTED_LOCATION ${lib_path})
82-
endforeach()
83-
84-
#To prevent 'undefined symbol: _ZN4llvm23EnableABIBreakingChecksE' error:
85-
add_compile_definitions(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING)
86-
87-
if(NOT ($ENV{target} MATCHES "darwin"))
88-
execute_process(COMMAND /bin/sh -c "nm -D -C ${CLANG_PREFIX}/lib/libclang.so | grep -q abi:cxx11" RESULT_VARIABLE rc)
89-
if(NOT (rc EQUAL 0)) #libclang.so compiled with cxx03 ABI
90-
add_compile_options(-D_GLIBCXX_USE_CXX11_ABI=0)
91-
endif()
92-
endif()
98+
# find_package(Clang) leads to errors with Clang_jll
99+
# due to inconsitency in the lists of expected and installed files
100+
101+
set(CLANG_PREFIX "" CACHE FILEPATH "Root path of libclang that contains lib/libclang.so.")
102+
if("${CLANG_PREFIX}" STREQUAL "")
103+
find_library(LIBCLANG_PATH_ clang REQUIRED NOCACHE)
104+
get_filename_component(CLANG_PREFIX "${LIBCLANG_PATH_}" DIRECTORY)
105+
get_filename_component(CLANG_PREFIX "${CLANG_PREFIX}" DIRECTORY)
106+
unset(LIBCLANG_PATH_)
107+
message(STATUS "CLANG_PREFIX: ${CLANG_PREFIX}")
108+
endif()
109+
include_directories("${CLANG_PREFIX}/include")
110+
111+
set(CLANG_RESOURCE_DIR "" CACHE STRING
112+
"Clang resource directory as returned by clang -print-resource-dir")
113+
if("${CLANG_RESOURCE_DIR}" STREQUAL "")
114+
message("Searching clang resource directory in " "${CLANG_PREFIX}/lib/clang")
115+
file(GLOB CLANG_RESOURCE_DIR_ "${CLANG_PREFIX}/lib/clang/*/include/stddef.h")
116+
if("${CLANG_RESOURCE_DIR_}" STREQUAL "")
117+
message(FATAL_ERROR "Failed to find Clang resource directory")
118+
else()
119+
list(GET CLANG_RESOURCE_DIR_ 0 CLANG_RESOURCE_DIR)
120+
unset(CLANG_RESOURCE_DIR_)
121+
get_filename_component(CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" DIRECTORY)
122+
get_filename_component(CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" DIRECTORY)
123+
message(STATUS "CLANG_RESOURCE_DIR: ${CLANG_RESOURCE_DIR}")
124+
endif()
125+
endif()
126+
127+
set(SHARED_LIBS libclang clang-cpp LLVM)
128+
foreach(shared_lib IN LISTS SHARED_LIBS)
129+
set(lib_path "${CLANG_PREFIX}/lib/lib${shared_lib}${CMAKE_SHARED_LIBRARY_SUFFIX}")
130+
string(REPLACE liblib lib lib_path ${lib_path})
131+
if(EXISTS "${lib_path}")
132+
add_library(${shared_lib} SHARED IMPORTED)
133+
else()
134+
set(lib_path "${CLANG_PREFIX}/lib/lib${shared_lib}${CMAKE_STATIC_LIBRARY_SUFFIX}")
135+
string(REPLACE liblib lib lib_path ${lib_path})
136+
if(EXISTS "${lib_path}")
137+
add_library(${shared_lib} STATIC IMPORTED)
138+
else()
139+
message(FATAL_ERROR "${shared_lib} library was not found in ${CLANG_PREFIX}/lib")
140+
endif()
141+
endif()
142+
set_property(TARGET ${shared_lib} PROPERTY
143+
IMPORTED_LOCATION ${lib_path})
144+
endforeach()
145+
146+
#To prevent 'undefined symbol: _ZN4llvm23EnableABIBreakingChecksE' error:
147+
add_compile_definitions(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING)
148+
149+
if(NOT ($ENV{target} MATCHES "darwin"))
150+
execute_process(COMMAND /bin/sh -c "nm -D -C ${CLANG_PREFIX}/lib/libclang.so | grep -q abi:cxx11" RESULT_VARIABLE rc)
151+
if(NOT (rc EQUAL 0)) #libclang.so compiled with cxx03 ABI
152+
add_compile_options(-D_GLIBCXX_USE_CXX11_ABI=0)
153+
endif()
154+
endif()
93155
endif()
94156

95-
96157
add_custom_target(version
97-
${CMAKE_COMMAND}
98-
-D SRC=${CMAKE_SOURCE_DIR}/src/version.cpp.in
99-
-D DST=${CMAKE_BINARY_DIR}/version.cpp
100-
-D GIT_EXECUTABLE=${GIT_EXECUTABLE}
101-
-P ${CMAKE_SOURCE_DIR}/version.cmake
102-
DEPENDS src/version.cpp.in
103-
)
158+
${CMAKE_COMMAND}
159+
-D SRC=${CMAKE_SOURCE_DIR}/src/version.cpp.in
160+
-D DST=${CMAKE_BINARY_DIR}/version.cpp
161+
-D GIT_EXECUTABLE=${GIT_EXECUTABLE}
162+
-P ${CMAKE_SOURCE_DIR}/version.cmake
163+
DEPENDS src/version.cpp.in
164+
)
104165

105166
# The target 'versions' is used to produce version.cpp
106167
# This dummy custom command is defined to allow
107168
# inclusion of version.cpp dependency to the
108169
# wrapit executable.
109170
add_custom_command(OUTPUT version.cpp
110-
COMMAND true
111-
)
171+
COMMAND true
172+
)
112173

113174
add_executable(wrapit
114-
src/TypeRcd.cpp
115-
src/TypeMapper.cpp
116-
src/utils.cpp
117-
src/cxxwrap_version.cpp
118-
src/uuid_utils.cpp
119-
src/libclang-ext.cpp
120-
src/FunctionWrapper.cpp
121-
src/CodeTree.cpp
122-
src/main.cpp
123-
src/toml.hpp
124-
src/md5sum.cpp
125-
src/FileTimeRestorer.cpp
126-
src/Graph.cpp
127-
version.cpp
175+
src/TypeRcd.cpp
176+
src/TypeMapper.cpp
177+
src/utils.cpp
178+
src/cxxwrap_version.cpp
179+
src/uuid_utils.cpp
180+
src/libclang-ext.cpp
181+
src/FunctionWrapper.cpp
182+
src/CodeTree.cpp
183+
src/main.cpp
184+
src/toml.hpp
185+
src/md5sum.cpp
186+
src/FileTimeRestorer.cpp
187+
src/Graph.cpp
188+
version.cpp
128189
)
129190

130191
add_dependencies(wrapit version)
131192

193+
194+
if(BUILD_LLVM)
195+
if(APPLE)
196+
set_target_properties(wrapit PROPERTIES INSTALL_RPATH @loader_path/../lib)
197+
else()
198+
set_target_properties(wrapit PROPERTIES INSTALL_RPATH $ORIGIN/../lib)
199+
endif()
200+
201+
target_include_directories(wrapit PRIVATE
202+
${llvm_SOURCE_DIR}/include
203+
${clang_SOURCE_DIR}/include
204+
${llvm_BINARY_DIR}/tools/clang/include
205+
${llvm_BINARY_DIR}/include)
206+
endif()
207+
132208
target_link_libraries(wrapit PRIVATE libclang clang-cpp LLVM cxxopts dl
133-
OpenSSL::Crypto)
209+
OpenSSL::Crypto
210+
#- gcc < 9.0 needs std++fs for the std::filesystem support
211+
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:stdc++fs>
212+
)
134213
set_target_properties(wrapit PROPERTIES
135-
CXX_STANDARD 17
136-
OUTPUT_NAME wrapit
137-
POSITION_INDEPENDENT_CODE ON #required for dladdrr on Linux (*)
138-
)
214+
CXX_STANDARD 17
215+
OUTPUT_NAME wrapit
216+
POSITION_INDEPENDENT_CODE ON #required for dladdrr on Linux (*)
217+
)
139218

140219
configure_file(src/config.h.in config.h @ONLY)
141220
include_directories(${CMAKE_CURRENT_BINARY_DIR}) #contains the generated config.h header file

test/runtests.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,16 @@ ENV["LOAD_PATH"] = "@:@stdlib"
3838
println("Try to run cmake...")
3939
#cmake based build
4040
# Configure and build with CMake
41-
run(`cmake --fresh -S $source_dir -B $build_dir`)
42-
run(`cmake --build $build_dir -t clean`)
43-
run(`cmake --build $build_dir -j $ncores`)
41+
rm(build_dir, recursive=true, force=true)
42+
mkdir(build_dir)
43+
run(`cmake -S "$source_dir" -B "$build_dir"`)
44+
run(`cmake --build "$build_dir" -t clean`)
45+
run(`cmake --build "$build_dir" -j $ncores`)
4446
else
4547
println("source_dir:", source_dir)
4648
#assumes plain make build
47-
run(`make -C $source_dir clean`)
48-
run(`make -C $source_dir -j $ncores`)
49+
run(`make -C "$source_dir" clean`)
50+
run(`make -C "$source_dir" -j $ncores`)
4951
end
5052
true
5153
catch

0 commit comments

Comments
 (0)