Skip to content

Commit b1e0853

Browse files
committed
fix(cmake): Add cmake install targets
Also, move the json AST printer to cxx-frontend.
1 parent 0851cf0 commit b1e0853

16 files changed

+179
-128
lines changed

CMakeLists.txt

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,20 @@ cmake_minimum_required(VERSION 3.16)
2222
project(cplusplus)
2323

2424
include(FetchContent)
25+
include(GNUInstallDirs)
26+
include(CMakePackageConfigHelpers)
2527

26-
find_package(fmt 8.0.1 CONFIG QUIET)
28+
find_package(fmt 7.1.3 CONFIG QUIET)
29+
30+
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version.txt" version)
2731

2832
set(CMAKE_CXX_STANDARD 20)
2933

3034
if(NOT fmt_FOUND)
3135
FetchContent_Declare(
3236
fmt
33-
GIT_REPOSITORY https://github.com/fmtlib/fmt
34-
GIT_TAG 7.1.3
37+
GIT_REPOSITORY https://github.com/fmtlib/fmt
38+
GIT_TAG 7.1.3
3539
GIT_SHALLOW 1
3640
)
3741

@@ -62,15 +66,21 @@ add_subdirectory(tools/kwgen)
6266

6367
aux_source_directory(src/cxx SOURCES)
6468

65-
add_library(CPlusPlus ${SOURCES}
69+
add_library(cxx ${SOURCES}
6670
# generated files
6771
keywords-priv.h
6872
)
6973

70-
target_include_directories(CPlusPlus PUBLIC src)
71-
target_include_directories(CPlusPlus PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
72-
target_link_libraries(CPlusPlus fmt::fmt-header-only utf8::cpp)
73-
target_link_libraries(CPlusPlus nlohmann_json::nlohmann_json)
74+
target_include_directories(cxx
75+
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
76+
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
77+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
78+
)
79+
80+
target_link_libraries(cxx
81+
PUBLIC $<BUILD_INTERFACE:fmt::fmt-header-only>
82+
$<BUILD_INTERFACE:utf8::cpp>
83+
)
7484

7585
add_custom_command(OUTPUT keywords-priv.h
7686
COMMAND kwgen < ${CMAKE_CURRENT_SOURCE_DIR}/src/cxx/keywords.kwgen > keywords-priv.h
@@ -80,7 +90,7 @@ add_custom_command(OUTPUT keywords-priv.h
8090
aux_source_directory(src/frontend FRONTEND_SOURCES)
8191

8292
add_executable(cxx-frontend ${FRONTEND_SOURCES})
83-
target_link_libraries(cxx-frontend CPlusPlus)
93+
target_link_libraries(cxx-frontend cxx nlohmann_json::nlohmann_json)
8494

8595
if(EMSCRIPTEN)
8696
target_link_options(cxx-frontend PUBLIC
@@ -94,7 +104,7 @@ if(EMSCRIPTEN)
94104

95105
add_executable(cxx-js src/cxx-js/api.cc)
96106

97-
target_link_libraries(cxx-js CPlusPlus)
107+
target_link_libraries(cxx-js cxx)
98108

99109
target_link_options(cxx-js PUBLIC
100110
"SHELL:--bind"
@@ -110,16 +120,47 @@ if(EMSCRIPTEN)
110120

111121
endif()
112122

113-
add_custom_target(unit
114-
DEPENDS tests/unit/source.cc
115-
COMMAND clang++ -E -stdlib=libc++ -xc++ -std=c++20 ${CMAKE_CURRENT_SOURCE_DIR}/tests/unit/source.cc | grep -v ^\# > unit.cc
123+
enable_testing()
124+
125+
add_subdirectory(tests)
126+
127+
file(GLOB CXX_INCLUDE_HEADER_FILES src/cxx/*.h)
128+
129+
configure_package_config_file(
130+
${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
131+
"${CMAKE_CURRENT_BINARY_DIR}/cxxConfig.cmake"
132+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cxx
116133
)
117134

118-
add_custom_target(unit.tokens
119-
DEPENDS unit cxx-frontend
120-
COMMAND cxx-frontend --dump-tokens unit.cc > unit.tokens
135+
write_basic_package_version_file(
136+
"${CMAKE_CURRENT_BINARY_DIR}/cxxConfigVersion.cmake"
137+
VERSION "${version}"
138+
COMPATIBILITY AnyNewerVersion
121139
)
122140

123-
enable_testing()
141+
install(
142+
TARGETS cxx
143+
EXPORT cxxTargets
144+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
145+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
146+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
147+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
148+
)
124149

125-
add_subdirectory(tests)
150+
install(
151+
EXPORT cxxTargets
152+
FILE cxxTargets.cmake
153+
NAMESPACE cxx::
154+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cxx
155+
)
156+
157+
install(
158+
FILES ${CXX_INCLUDE_HEADER_FILES}
159+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cxx
160+
)
161+
162+
install(FILES
163+
"${CMAKE_CURRENT_BINARY_DIR}/cxxConfig.cmake"
164+
"${CMAKE_CURRENT_BINARY_DIR}/cxxConfigVersion.cmake"
165+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cxx
166+
)

Config.cmake.in

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2014-2020 Roberto Raggi <[email protected]>
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
# this software and associated documentation files (the "Software"), to deal in
5+
# the Software without restriction, including without limitation the rights to
6+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7+
# the Software, and to permit persons to whom the Software is furnished to do so,
8+
# subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
@PACKAGE_INIT@
21+
22+
include("${CMAKE_CURRENT_LIST_DIR}/cxxTargets.cmake")
23+
24+
check_required_components(cxx)

src/cxx/diagnostics_client.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222

2323
// cxx
2424
#include <cxx/preprocessor.h>
25+
#include <fmt/format.h>
26+
#include <fmt/ostream.h>
2527

2628
#include <cctype>
29+
#include <cstdlib>
2730
#include <iostream>
2831

2932
namespace cxx {
@@ -72,6 +75,10 @@ void DiagnosticsClient::report(const Diagnostic& diag) {
7275
} else {
7376
fmt::print(std::cerr, "{}\n", diag.message());
7477
}
78+
79+
if (diag.severity() == Severity::Fatal ||
80+
(diag.severity() == Severity::Error && fatalErrors_))
81+
exit(EXIT_FAILURE);
7582
}
7683

7784
} // namespace cxx

src/cxx/diagnostics_client.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@
2222

2323
#include <cxx/diagnostic.h>
2424

25-
// fmt
26-
#include <fmt/format.h>
27-
#include <fmt/ostream.h>
28-
29-
#include <cstdlib>
30-
3125
namespace cxx {
3226

3327
class Preprocessor;
@@ -57,19 +51,12 @@ class DiagnosticsClient {
5751
return blockErrors;
5852
}
5953

60-
template <typename... Args>
61-
void report(const Token& token, Severity kind, const std::string_view& format,
62-
const Args&... args) {
54+
void report(const Token& token, Severity severity, std::string message) {
6355
if (blockErrors_) return;
6456

65-
Diagnostic diag(kind, token,
66-
fmt::vformat(format, fmt::make_format_args(args...)));
57+
Diagnostic diag{severity, token, std::move(message)};
6758

6859
report(diag);
69-
70-
if (diag.severity() == Severity::Fatal ||
71-
(diag.severity() == Severity::Error && fatalErrors_))
72-
exit(EXIT_FAILURE);
7360
}
7461

7562
private:
@@ -78,4 +65,4 @@ class DiagnosticsClient {
7865
bool fatalErrors_ = false;
7966
};
8067

81-
} // namespace cxx
68+
} // namespace cxx

src/cxx/expression_codegen.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <cxx/type_environment.h>
3232
#include <cxx/type_visitor.h>
3333
#include <cxx/types.h>
34+
#include <fmt/format.h>
35+
#include <fmt/ostream.h>
3436

3537
#include <stdexcept>
3638

src/cxx/literals.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
// SOFTWARE.
2020

2121
#include <cxx/cxx_fwd.h>
22-
#include <fmt/format.h>
2322

2423
#include <cstdlib>
2524
#include <string>

src/cxx/parser.cc

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <cxx/token.h>
3030
#include <cxx/type_environment.h>
3131
#include <cxx/types.h>
32+
#include <fmt/format.h>
33+
#include <fmt/ostream.h>
3234

3335
#include <algorithm>
3436
#include <cassert>
@@ -208,6 +210,31 @@ const Token& Parser::LA(int n) const {
208210
return unit->tokenAt(SourceLocation(cursor_ + n));
209211
}
210212

213+
bool Parser::match(TokenKind tk) {
214+
if (LA().isNot(tk)) return false;
215+
(void)consumeToken();
216+
return true;
217+
}
218+
219+
bool Parser::match(TokenKind tk, SourceLocation& location) {
220+
if (LA().isNot(tk)) return false;
221+
const auto loc = consumeToken();
222+
location = loc;
223+
return true;
224+
}
225+
226+
bool Parser::expect(TokenKind tk) {
227+
if (match(tk)) return true;
228+
parse_error(fmt::format("expected '{}'", Token::spell(tk)));
229+
return false;
230+
}
231+
232+
bool Parser::expect(TokenKind tk, SourceLocation& location) {
233+
if (match(tk, location)) return true;
234+
parse_error(fmt::format("expected '{}'", Token::spell(tk)));
235+
return false;
236+
}
237+
211238
bool Parser::operator()(UnitAST*& ast) {
212239
auto result = parse(ast);
213240
return result;
@@ -604,13 +631,13 @@ bool Parser::parse_primary_expression(ExpressionAST*& yyast,
604631
ast->symbol = sem->scope()->unqualifiedLookup(nameSem.name);
605632

606633
if (!ast->symbol)
607-
parse_warn(ast->name->firstSourceLocation(), "undefined symbol '{}'",
608-
*nameSem.name);
634+
parse_warn(ast->name->firstSourceLocation(),
635+
fmt::format("undefined symbol '{}'", *nameSem.name));
609636
else {
610637
#if 0
611638
parse_warn(ast->name->firstSourceLocation(),
612-
"'{}' resolved to '{}' with type '{}'", *nameSem.name,
613-
typeid(*ast->symbol).name(), ast->symbol->type());
639+
fmt::format("'{}' resolved to '{}' with type '{}'", *nameSem.name,
640+
typeid(*ast->symbol).name(), ast->symbol->type()));
614641
#endif
615642
}
616643
}

src/cxx/parser.h

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -76,33 +76,25 @@ class Parser final {
7676
bool templArg = false;
7777
};
7878

79-
template <typename... Args>
80-
bool parse_warn(const std::string_view& format, const Args&... args) {
81-
unit->warning(SourceLocation(cursor_), format, args...);
79+
bool parse_warn(std::string message) {
80+
unit->warning(SourceLocation(cursor_), std::move(message));
8281
return true;
8382
}
8483

85-
template <typename... Args>
86-
bool parse_warn(SourceLocation loc, const std::string_view& format,
87-
const Args&... args) {
88-
unit->warning(loc, format, args...);
84+
bool parse_warn(SourceLocation loc, std::string message) {
85+
unit->warning(loc, std::move(message));
8986
return true;
9087
}
9188

92-
template <typename... Args>
93-
bool parse_error(const std::string_view& format, const Args&... args) {
89+
bool parse_error(std::string message) {
9490
if (lastErrorCursor_ == cursor_) return true;
9591
lastErrorCursor_ = cursor_;
96-
unit->error(SourceLocation(cursor_), format, args...);
97-
// throw std::runtime_error("error");
92+
unit->error(SourceLocation(cursor_), std::move(message));
9893
return true;
9994
}
10095

101-
template <typename... Args>
102-
bool parse_error(SourceLocation loc, const std::string_view& format,
103-
const Args&... args) {
104-
unit->error(loc, format, args...);
105-
// throw std::runtime_error("error");
96+
bool parse_error(SourceLocation loc, std::string message) {
97+
unit->error(loc, std::move(message));
10698
return true;
10799
}
108100

@@ -437,30 +429,11 @@ class Parser final {
437429
private:
438430
const Token& LA(int n = 0) const;
439431

440-
bool match(TokenKind tk) {
441-
if (LA().isNot(tk)) return false;
442-
(void)consumeToken();
443-
return true;
444-
}
445-
446-
bool expect(TokenKind tk) {
447-
if (match(tk)) return true;
448-
parse_error("expected '{}'", Token::spell(tk));
449-
return false;
450-
}
432+
bool match(TokenKind tk);
433+
bool match(TokenKind tk, SourceLocation& location);
451434

452-
bool match(TokenKind tk, SourceLocation& location) {
453-
if (LA().isNot(tk)) return false;
454-
const auto loc = consumeToken();
455-
location = loc;
456-
return true;
457-
}
458-
459-
bool expect(TokenKind tk, SourceLocation& location) {
460-
if (match(tk, location)) return true;
461-
parse_error("expected '{}'", Token::spell(tk));
462-
return false;
463-
}
435+
bool expect(TokenKind tk);
436+
bool expect(TokenKind tk, SourceLocation& location);
464437

465438
SourceLocation consumeToken() { return SourceLocation(cursor_++); }
466439

0 commit comments

Comments
 (0)