Skip to content

Commit ef7998e

Browse files
committed
cmx for c++
1 parent b2be20a commit ef7998e

File tree

6 files changed

+110
-21
lines changed

6 files changed

+110
-21
lines changed

Makefile

+4-5
Original file line numberDiff line numberDiff line change
@@ -494,16 +494,15 @@ build-beeware-ext: clean-static-ext
494494
$(call call-builder,"pyjs" "beeware_ext" "--build" "--release")
495495

496496

497-
# re-compile only
497+
# cython re-generation of api.c only if api.pyx is modified
498498
# -----------------------------------------------------------------------
499-
.PHONY: compile-extension api
499+
.PHONY: api
500500

501-
compile-extension:
501+
source/projects/py/api.c: source/projects/py/api.pyx
502502
$(call section,"generate c code from cython extension")
503503
@cython -3 $(CYTHON_OPTIONS) $(EXTENSION)
504504

505-
api: compile-extension
506-
505+
api: source/projects/py/api.c
507506

508507
# -----------------------------------------------------------------------
509508
# utilities

requirements.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
cython
2-

source/demos/cmx/CMakeLists.txt

+20-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake)
22
include(${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/cmake/common.cmake)
33

4-
54
#############################################################
65
# CMX: Common Max Library
76
#############################################################
87

9-
enable_language(C)
8+
option(CPP_HEADER "Use in c++ external" OFF)
109

1110

1211
include_directories(
@@ -15,18 +14,32 @@ include_directories(
1514
"${MAX_SDK_JIT_INCLUDES}"
1615
)
1716

18-
file(GLOB PROJECT_SRC
19-
"*.h"
20-
"*.c"
21-
"*.cpp"
22-
)
17+
if(CPP_HEADER)
18+
set(PROJECT_SRC cmx.cpp)
19+
else()
20+
set(PROJECT_SRC cmx.c)
21+
endif()
2322

2423
add_library(
2524
${PROJECT_NAME}
2625
STATIC
2726
${PROJECT_SRC}
2827
)
2928

29+
if(CPP_HEADER)
30+
target_compile_features(
31+
${PROJECT_NAME}
32+
PRIVATE
33+
cxx_std_17
34+
)
35+
target_compile_definitions(
36+
${PROJECT_NAME}
37+
PRIVATE
38+
CMX_CPP_HEADER
39+
)
40+
endif()
41+
42+
3043

3144
# header propogates to sibling directories which link to this target (cmx)
3245
# see: https://stackoverflow.com/questions/61709086/cmake-target-with-sibling-folders

source/demos/cmx/cmx.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#define CMX_IMPLEMENTATION
2+
#include "cmx.h"
3+
4+
/**
5+
* empty file to facilitate compilation as static lib
6+
*/

source/demos/cmx/cmx.h

+69-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#include "ext.h"
1919
#include "ext_obex.h"
2020

21+
#ifdef CMX_CPP_HEADER
22+
#include <string>
23+
#include <filesystem>
24+
namespace fs = std::filesystem;
25+
#endif
2126

2227
// ---------------------------------------------------------------------------
2328
// constants
@@ -28,9 +33,13 @@
2833
// ---------------------------------------------------------------------------
2934
// forward declarations
3035

31-
// t_symbol* locate_path_to_external(t_class* c);
36+
#ifdef CMX_CPP_HEADER
37+
std::string get_path_to_external(t_class* c, char* subpath);
38+
std::string get_path_to_package(t_class* c, char* subpath);
39+
#else
3240
t_string* get_path_to_external(t_class* c, char* subpath);
3341
t_string* get_path_to_package(t_class* c, char* subpath);
42+
#endif
3443
t_object* create_object(t_object* x, const char* text);
3544
void path_basename(const char* path, char* filename);
3645
void path_dirname(const char* path, char* parent_directory);
@@ -45,6 +54,63 @@ void path_join(char* destination, const char* path1, const char* path2);
4554
#ifdef CMX_IMPLEMENTATION
4655

4756

57+
#ifdef CMX_CPP_HEADER
58+
/**
59+
* @brief Return path to external with optional subpath
60+
*
61+
* @param c t_class instance
62+
* @param subpath The subpath or NULL (if not)
63+
*
64+
* @return path to external + (optional subpath)
65+
*/
66+
std::string get_path_to_external(t_class* c, char* subpath)
67+
{
68+
char external_path[MAX_PATH_CHARS];
69+
char external_name[MAX_PATH_CHARS];
70+
char conform_path[MAX_PATH_CHARS];
71+
short path_id = class_getpath(c);
72+
fs::path result;
73+
74+
#ifdef __APPLE__
75+
const char* ext_filename = "%s.mxo";
76+
#else
77+
const char* ext_filename = "%s.mxe64";
78+
#endif
79+
snprintf_zero(external_name, MAX_FILENAME_CHARS, ext_filename, c->c_sym->s_name);
80+
path_toabsolutesystempath(path_id, external_name, external_path);
81+
path_nameconform(external_path, conform_path, PATH_STYLE_NATIVE,
82+
PATH_TYPE_TILDE);
83+
result = fs::path(external_path);
84+
if (subpath != NULL) {
85+
result /= subpath;
86+
}
87+
return result.string();
88+
}
89+
90+
91+
/**
92+
* @brief Return path to package with optional subpath
93+
*
94+
* @param c t_class instance
95+
* @param subpath The subpath or NULL (if not)
96+
*
97+
* @return path to package + (optional subpath)
98+
*/
99+
std::string get_path_to_package(t_class* c, char* subpath)
100+
{
101+
fs::path external_path = fs::path(get_path_to_external(c, NULL));
102+
fs::path externals_folder = external_path.parent_path();
103+
fs::path package_folder = externals_folder.parent_path();
104+
105+
if (subpath != NULL) {
106+
package_folder /= subpath;
107+
}
108+
109+
return package_folder.string();
110+
}
111+
112+
#else
113+
48114
/**
49115
* @brief Return path to external with optional subpath
50116
*
@@ -112,6 +178,8 @@ t_string* get_path_to_package(t_class* c, char* subpath)
112178
return result;
113179
}
114180

181+
#endif
182+
115183

116184
/**
117185
* @brief Create a new object from a box text

source/projects/py/CMakeLists.txt

+11-7
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/cmake/common.cmake)
33

44
option(INCLUDE_NUMPY "include numpy headers if available")
55
option(INCLUDE_COMMONSYMS "include commmonsym.c")
6-
option(INCLUDE_API_MODULE "include cython api c module" ON)
6+
option(INCLUDE_API_MODULE "include api c module" ON)
7+
option(REGEN_API_MODULE "enable cython regen of api.c if api.pyx is modified")
78

89

910
set(SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
11+
set(API_PYX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/api.pyx)
12+
set(API_C_FILE ${CMAKE_CURRENT_SOURCE_DIR}/api.c)
1013

1114

1215
find_package(Python3 COMPONENTS Interpreter Development)
1316

1417

1518
set(PROJECT_SRC
1619
${CMAKE_CURRENT_SOURCE_DIR}/py.c
17-
$<$<BOOL:${INCLUDE_API_MODULE}>:${CMAKE_CURRENT_SOURCE_DIR}/api.c>
20+
$<$<BOOL:${INCLUDE_API_MODULE}>:${API_C_FILE}>
1821
)
1922

2023
include_directories(
@@ -79,18 +82,19 @@ target_compile_options(
7982
$<$<PLATFORM_ID:Windows>:/MD> # api module works with this
8083
)
8184

82-
if(INCLUDE_API_MODULE)
85+
if(INCLUDE_API_MODULE AND REGEN_API_MODULE)
8386

8487
add_custom_command(
85-
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/api.c
86-
COMMAND cython -3 --timestamps -E INCLUDE_NUMPY=${CYTHON_INCL_NUMPY} api.pyx
88+
OUTPUT ${API_C_FILE}
89+
DEPENDS ${API_PYX_FILE}
90+
COMMAND cython -3 --timestamps -E INCLUDE_NUMPY=${CYTHON_INCL_NUMPY} ${API_PYX_FILE}
8791
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
88-
DEPENDS api.pyx
8992
COMMENT "Generating api.c"
9093
)
9194

9295
add_custom_target(api_c
93-
DEPENDS api.pyx
96+
ALL
97+
DEPENDS ${API_C_FILE}
9498
)
9599

96100
add_dependencies(${PROJECT_NAME} api_c)

0 commit comments

Comments
 (0)