Skip to content

Commit 25301bb

Browse files
committed
Rewrite ldc2.conf cmake generation
When building, always generate separate files for each ldc2.conf section. This allows creating a full ldc2.conf, part by part, without carrying about the statements' order in the cmake file. When installing, `cat` all the configured files and install it as a single ldc2.conf file. Added the CONF_PREF_DIR cmake option for installing the conf files as a directory, without concatenating them. This is useful when building the runtime as a separate project as this setting would allow generating a (partial) ldc2.conf, enough to support the runtime libraries, which could latter be merged with the config generated by the root ldc project to get a fully functional ldc2. This is a requirement when cross-compiling and installing the libraries on another device or when performing multilib builds outside of -DMULTILIB=ON Also add a more detailed documentation about the configuration. Signed-off-by: Andrei Horodniceanu <[email protected]>
1 parent 558632e commit 25301bb

File tree

13 files changed

+584
-290
lines changed

13 files changed

+584
-290
lines changed

.github/actions/5-install/action.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ runs:
5050
# /d/a/1/install => D:/a/1/install
5151
absInstallDir=$(cygpath --mixed "$absInstallDir")
5252
fi
53-
perl -pi -e "s|$absInstallDir/|%%ldcbinarypath%%/../|g" install/etc/ldc2.conf
54-
cat install/etc/ldc2.conf
53+
confs=( install/etc/ldc2.conf/* )
54+
perl -pi -e "s|$absInstallDir/|%%ldcbinarypath%%/../|g" "${confs[@]}"
55+
cat "${confs[@]}"
5556
5657
- name: Rename the installation dir to test portability
5758
shell: bash

.github/actions/merge-macos/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ runs:
4141
# ldc2.conf:
4242
# 1) make a backup copy
4343
cp etc/ldc2.conf /tmp/ldc2.conf.bak
44-
# 2) strip to the header comments (remove all existing sections, only keep `default:` line)
45-
sed -i '' '/^default:$/q' etc/ldc2.conf
44+
# 2) strip to the header comments (remove all existing sections, only keep `default:` or `"default":` line)
45+
sed -E -i '' '/^"?default"?:$/q' etc/ldc2.conf
4646
# 3) append all sections (except for wasm)
4747
cat >>etc/ldc2.conf <<EOF
4848
{

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
#### Big news
44
- Frontend, druntime and Phobos are at version ~[2.112.0](https://dlang.org/changelog/2.112.0.html), incl. new command-line options `-extI`, `-dllimport=externalOnly` and `-edition`. (#4949, #4962)
5-
- **Breaking change for dcompute**: The special `@kernel` UDA is now a function and _**requires**_ parentheses as in `@kernel() void foo(){}`. Optionally you can provide launch dimensions, `@kernel([2,4,8])`, to specify to the compute runtime how the kernel is intended to be launched.
5+
- **Breaking change for dcompute**: The special `@kernel` UDA is now a function and _**requires**_ parentheses as in `@kernel() void foo(){}`. Optionally you can provide launch dimensions, `@kernel([2,4,8])`, to specify to the compute runtime how the kernel is intended to be launched.
6+
- ldc2.conf can now be a directory. All the files inside it, ordered naturally, will be concatenated and treated like a big config. (#4954)
7+
- **Breaking change for ldc2.conf cmake generation**: The `cmake` build process now generates the `ldc2.conf` and `ldc2_install.conf` as directories. `ldc2*.conf.in` and `ADDITIONAL_DEFAULT_LDC_SWITCHES` have been removed, if you need to add switches check out `makeConfSection` in `LdcConfig.cmake`. (#4954)
68

79
#### Platform support
810

CMakeLists.txt

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,14 @@ project(ldc)
1717

1818
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
1919

20+
include(LdcCommon)
21+
2022
include(FindDCompiler)
2123
include(CheckCXXCompilerFlag)
2224
include(CheckDSourceCompiles)
2325
include(CheckLinkFlag)
2426
include(BuildDExecutable)
2527

26-
# Helper function
27-
function(append value)
28-
foreach(variable ${ARGN})
29-
if(${variable} STREQUAL "")
30-
set(${variable} "${value}" PARENT_SCOPE)
31-
else()
32-
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
33-
endif()
34-
endforeach(variable)
35-
endfunction()
36-
3728
#
3829
# Locate LLVM.
3930
#
@@ -128,21 +119,9 @@ set(DMDFE_PATCH_VERSION 0)
128119

129120
set(DMD_VERSION ${DMDFE_MAJOR_VERSION}.${DMDFE_MINOR_VERSION}.${DMDFE_PATCH_VERSION})
130121

131-
# Generally, we want to install everything into CMAKE_INSTALL_PREFIX, but when
132-
# it is /usr, put the config files into /etc to meet common practice.
133-
if(NOT DEFINED SYSCONF_INSTALL_DIR)
134-
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
135-
set(SYSCONF_INSTALL_DIR "/etc")
136-
else()
137-
set(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc")
138-
endif()
139-
endif()
140-
141122
set(D_VERSION ${DMDFE_MAJOR_VERSION} CACHE STRING "D language version")
142123
set(PROGRAM_PREFIX "" CACHE STRING "Prepended to ldc/ldmd binary names")
143124
set(PROGRAM_SUFFIX "" CACHE STRING "Appended to ldc/ldmd binary names")
144-
set(CONF_INST_DIR ${SYSCONF_INSTALL_DIR} CACHE PATH "Directory ldc2.conf is installed to")
145-
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/d CACHE PATH "Path to install D modules to")
146125

147126
# Note: LIB_SUFFIX should perhaps be renamed to LDC_LIBDIR_SUFFIX.
148127
set(LIB_SUFFIX "" CACHE STRING "Appended to the library installation directory. Set to '64' to install libraries into ${PREFIX}/lib64.")
@@ -925,7 +904,7 @@ if(NOT DEFINED COMPILER_RT_LIBDIR_CONFIG)
925904
endif()
926905
if(DEFINED COMPILER_RT_LIBDIR_CONFIG)
927906
message(STATUS "Adding ${COMPILER_RT_LIBDIR_CONFIG} to lib-dirs in configuration file")
928-
set(OPTIONAL_COMPILER_RT_DIR "\n \"${COMPILER_RT_LIBDIR_CONFIG}\", // compiler-rt directory")
907+
makeConfSection(NAME "35-ldc-compiler-rt" SECTION "default" LIB_DIRS "${COMPILER_RT_LIBDIR}")
929908
endif()
930909

931910
#
@@ -1006,6 +985,15 @@ option(LDC_BUILD_RUNTIME "Build the runtime libraries" ${_LDC_BUILD_RUNTIME_DEFA
1006985

1007986
if(LDC_BUILD_RUNTIME)
1008987
add_subdirectory(runtime)
988+
989+
# POST_BUILD can't be used for targets in a different directory so
990+
# runtime/CMakeLists.txt can't directly add the commands.
991+
if(_LDC_POST_BUILD_COMMANDS)
992+
add_custom_command(TARGET ${LDC_EXE} POST_BUILD
993+
${_LDC_POST_BUILD_COMMANDS}
994+
BYPRODUCTS ${_LDC_POST_BUILD_BYPRODUCTS}
995+
)
996+
endif()
1009997
else()
1010998
message(STATUS "NOT building the runtime libraries (LDC_BUILD_RUNTIME=OFF)")
1011999
endif()
@@ -1045,6 +1033,11 @@ if(${BUILD_SHARED})
10451033
install(TARGETS ${LDC_LIB} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
10461034
endif()
10471035

1036+
# Add some documentation to the installed config files
1037+
if(NOT DONT_INSTALL_CONF)
1038+
install(FILES "ldc2.conf.header" DESTINATION "${CONF_INST_DIR}/ldc2.conf" RENAME 00-docs.conf)
1039+
endif()
1040+
10481041
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
10491042
if(NOT DEFINED BASH_COMPLETION_COMPLETIONSDIR)
10501043
find_package(bash-completion QUIET)

cmake/Modules/LdcCommon.cmake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Common functionality shared by the compiler and the runtime build system.
2+
3+
function(append value)
4+
foreach(variable ${ARGN})
5+
if(${variable} STREQUAL "")
6+
set(${variable} "${value}" PARENT_SCOPE)
7+
else()
8+
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
9+
endif()
10+
endforeach(variable)
11+
endfunction()
12+
13+
include(LdcConfig)

cmake/Modules/LdcConfig.cmake

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Functions used for generating and installing ldc2.conf
2+
3+
function(defineIfUnset variable)
4+
if(ARGC EQUAL 1)
5+
set(args)
6+
else()
7+
list(SUBLIST ARGV 1 -1 args)
8+
endif()
9+
10+
if(NOT DEFINED ${variable})
11+
set(${variable} ${args} PARENT_SCOPE)
12+
endif()
13+
endfunction()
14+
15+
function(formatArray out_var)
16+
if(ARGC EQUAL 1)
17+
set(${out_var} "[]" PARENT_SCOPE)
18+
return()
19+
endif()
20+
21+
list(SUBLIST ARGV 1 -1 values)
22+
set(result "[")
23+
foreach(value ${values})
24+
set(result "${result}\n \"${value}\",")
25+
endforeach()
26+
set(result "${result}\n ]")
27+
28+
set(${out_var} "${result}" PARENT_SCOPE)
29+
endfunction()
30+
31+
function(formatArraySetting out_var name)
32+
if(ARGC EQUAL 2)
33+
# Ignore `value ~= []`
34+
set(${out_var} "" PARENT_SCOPE)
35+
return()
36+
endif()
37+
38+
list(SUBLIST ARGV 2 -1 values)
39+
list(GET values 0 maybe_override)
40+
if(maybe_override STREQUAL "OVERRIDE")
41+
set(operator "=")
42+
list(POP_FRONT values)
43+
else()
44+
set(operator "~=")
45+
endif()
46+
formatArray(array ${values})
47+
set(${out_var} "\n ${name} ${operator} ${array};" PARENT_SCOPE)
48+
endfunction()
49+
50+
function(formatScalarSetting out_var name)
51+
if(ARGC EQUAL 2)
52+
set(${out_var} "" PARENT_SCOPE)
53+
else()
54+
set(${out_var} "\n ${name} = \"${ARGV2}\";" PARENT_SCOPE)
55+
endif()
56+
endfunction()
57+
58+
59+
# Create a ldc2.conf section
60+
#
61+
# Example:
62+
#
63+
# makeConfSectionImpl(
64+
# FILEPATH "${CMAKE_BINARY_DIR}/ldc2.conf"
65+
# # The output filename
66+
#
67+
# SECTION "^wasm(32|64)-"
68+
# # A regex to match a target triple or "default"
69+
#
70+
# SWITCHES -d-version=foo -L--linker-flag
71+
# # The `switches` list
72+
#
73+
# POST_SWITCHES OVERRIDE -I/path/to/druntime/src
74+
# # The `post-switches` list
75+
#
76+
# LIB_DIRS "${CMAKE_BINARY_DIR}/lib64"
77+
# # The `lib-dirs` list
78+
#
79+
# RPATH "/path/to/dir"
80+
# # The `rpath` value
81+
# )
82+
#
83+
# Would generate:
84+
#
85+
# $ cat "${CMAKE_BINARY_DIR}/ldc2.conf"
86+
# "^wasm(32|64)-":
87+
# {
88+
# switches ~= [
89+
# "-d-version=foo",
90+
# "-L--linker-flag",
91+
# ];
92+
# post-switches = [
93+
# "-I/path/to/druntime/src"
94+
# ];
95+
# lib-dirs ~= [
96+
# "${CMAKE_BINARY_DIR}/lib64"
97+
# ];
98+
# rpath = "/path/to/dir"
99+
# }
100+
#
101+
# You don't need to pass all setting keys, only the ones that have values.
102+
#
103+
# Array settings (SWITCHES, POST_SWITCHES, LIB_DIRS) may start with an
104+
# OVERRIDE signifying that they should overwrite the (possibly)
105+
# previously stored values. The default is to append to them.
106+
function(makeConfSectionImpl)
107+
set(oneValueArgs FILEPATH SECTION RPATH)
108+
set(multiValueArgs SWITCHES POST_SWITCHES LIB_DIRS)
109+
cmake_parse_arguments(args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
110+
111+
foreach(var FILEPATH SECTION)
112+
if(NOT DEFINED args_${var})
113+
message(SEND_ERROR "Expected ${var} argument")
114+
endif()
115+
endforeach()
116+
if(DEFINED args_UNPARSED_ARGUMENTS)
117+
message(SEND_ERROR "Unexpected arguments: ${args_UNPARSED_ARGUMENTS}")
118+
endif()
119+
120+
formatArraySetting(switches "switches" ${args_SWITCHES})
121+
formatArraySetting(post_switches "post-switches" ${args_POST_SWITCHES})
122+
formatArraySetting(lib_dirs "lib-dirs" ${args_LIB_DIRS})
123+
# Support `RPATH ""` to clear the setting
124+
set(rpath)
125+
if(args_RPATH OR "RPATH" IN_LIST args_KEYWORDS_MISSING_VALUES)
126+
formatScalarSetting(rpath "rpath" "${args_RPATH}")
127+
endif()
128+
129+
file(WRITE "${args_FILEPATH}"
130+
"\"${args_SECTION}\":\n"
131+
"{"
132+
"${switches}"
133+
"${post_switches}"
134+
"${lib_dirs}"
135+
"${rpath}"
136+
"\n};\n"
137+
)
138+
endfunction()
139+
140+
# Create a ldc2.conf section
141+
#
142+
# Example:
143+
#
144+
# makeConfSection(
145+
# NAME 40-runtime
146+
# # a unique name for the file that will store this section
147+
#
148+
# SECTION "x86_64-.*-linux-gnu"
149+
# # A regex for a target triple or the string "default"
150+
#
151+
# BUILD
152+
# # Settings for ldc2.conf when part of this cmake project
153+
# SWITCHES -a -b
154+
# POST_SWITCHES -I${CMAKE_SOURCE_DIR}/runtime/import -c
155+
#
156+
# INSTALL
157+
# # Settings for ldc2.conf when installed on a user system
158+
# SWITCHES OVERRIDE -bar
159+
# LIB_DIRS "${CMAKE_INSTALL_PREFIX}/lib"
160+
# RPATH "${CMAKE_INSTALL_PREFIX}/lib"
161+
# )
162+
#
163+
# The possible settings are described by makeConfSectionImpl.
164+
#
165+
# As a shortcut the BUILD and INSTALL arguments may be omitted, making the
166+
# settings be applied to both build and install ldc2.conf. Example:
167+
#
168+
# makeConfSection(NAME 10-example SECTION default
169+
# SWITCHES -my-important-switch
170+
# )
171+
#
172+
# Is equivalent to:
173+
#
174+
# makeConfSection(NAME 10-example SECTION default
175+
# BUILD
176+
# SWITCHES -my-important-switch
177+
# INSTALL
178+
# SWITCHES -my-important-switch
179+
# )
180+
#
181+
# It is also possible to generate a configuration file for either only the build
182+
# or only the install. Simply pass only BUILD or INSTALL to this function.
183+
function(makeConfSection)
184+
set(oneValueArgs NAME SECTION)
185+
set(multiValueArgs BUILD INSTALL)
186+
cmake_parse_arguments(PARSE_ARGV 0 args "" "${oneValueArgs}" "${multiValueArgs}")
187+
188+
foreach(var ${oneValueArgs})
189+
if(NOT DEFINED args_${var})
190+
message(SEND_ERROR "Expected defined ${var} argument")
191+
endif()
192+
endforeach()
193+
if(DEFINED args_UNPARSED_ARGUMENTS)
194+
if(NOT DEFINED args_BUILD AND NOT DEFINED args_INSTALL)
195+
set(args_BUILD "${args_UNPARSED_ARGUMENTS}")
196+
set(args_INSTALL "${args_UNPARSED_ARGUMENTS}")
197+
else()
198+
message(SEND_ERROR "Unexpected arguments: ${args_UNPARSED_ARGUMENTS}")
199+
endif()
200+
endif()
201+
202+
if(args_BUILD)
203+
set(build_conf "${LDC_BUILD_CONF}/${args_NAME}.conf")
204+
makeConfSectionImpl(FILEPATH "${build_conf}" SECTION "${args_SECTION}" ${args_BUILD})
205+
endif()
206+
if(args_INSTALL)
207+
set(install_conf "${LDC_INSTALL_CONF}/${args_NAME}.conf")
208+
makeConfSectionImpl(FILEPATH "${install_conf}" SECTION "${args_SECTION}" ${args_INSTALL})
209+
if(NOT DONT_INSTALL_CONF)
210+
install(FILES "${install_conf}" DESTINATION "${CONF_INST_DIR}/ldc2.conf")
211+
endif()
212+
endif()
213+
endfunction()
214+
215+
# Generally, we want to install everything into CMAKE_INSTALL_PREFIX, but when
216+
# it is /usr, put the config files into /etc to meet common practice.
217+
if(NOT DEFINED SYSCONF_INSTALL_DIR)
218+
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
219+
set(SYSCONF_INSTALL_DIR "/etc")
220+
else()
221+
set(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc")
222+
endif()
223+
endif()
224+
225+
set(CONF_INST_DIR ${SYSCONF_INSTALL_DIR} CACHE PATH "Directory in which to install ldc2.conf")
226+
if(CONF_INST_DIR STREQUAL "")
227+
set(DONT_INSTALL_CONF TRUE)
228+
else()
229+
set(DONT_INSTALL_CONF FALSE)
230+
endif()
231+
232+
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/d CACHE PATH "Path to install D modules to")
233+
234+
defineIfUnset(LDC_BUILD_CONF "${CMAKE_BINARY_DIR}/etc/ldc2.conf")
235+
defineIfUnset(LDC_INSTALL_CONF "${CMAKE_BINARY_DIR}/etc/ldc2_install.conf")

0 commit comments

Comments
 (0)