diff --git a/setup.py b/setup.py index cfbaa55..51b6dbb 100644 --- a/setup.py +++ b/setup.py @@ -108,7 +108,18 @@ def copy_extensions_to_source(self): def run(self): shared_options.load(self) try: - super().run() + # We need to compute the install directory here, because + # build_ext.run() unsets build_ext.inplace while running + # build_extension(). This means that files would be installed + # to the wrong location (to the temporary build directory) + # for `setup.py develop`/`pip install -e` builds. + self.install_dirs = {} + for ext in self.extensions: + if isinstance(ext, CMakeExtension): + self.install_dirs[ext] = os.path.join( + os.path.abspath( + os.path.dirname(self.get_ext_fullpath(ext.name))), + ext.prefix) try: out = subprocess.check_output(['cmake', '--version']) @@ -123,8 +134,7 @@ def run(self): if cmake_version < '3.7.0': raise RuntimeError("CMake >= 3.7.0 is required.") - for ext in self.extensions: - self.build_extension(ext) + super().run() except BaseException as e: print( @@ -163,13 +173,9 @@ def add_flags(self): def build_extension(self, ext): if isinstance(ext, CMakeExtension): - extdir = os.path.join( - os.path.abspath( - os.path.dirname(self.get_ext_fullpath(ext.name))), - ext.prefix) + extdir = self.install_dirs[ext] cmake_args = [ - '-DCMAKE_INSTALL_PREFIX=' + extdir, - '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + '-DCMAKE_INSTALL_PREFIX=' + extdir, '-DCMAKE_INSTALL_LIBDIR=.', '-DPYTHON_EXECUTABLE=' + sys.executable, '-DANTLR_RUNTIME_TYPE=' + shared_options.antlr_runtime ] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94783a6..f407785 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,7 +57,7 @@ include_directories(${ANTLR4_INCLUDE_DIRS}) # set variable pointing to the antlr tool that supports C++ # this is not required if the jar file can be found under PATH environment -set(ANTLR_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/antlr4_lib/antlr-4.9.3-complete.jar) +set(ANTLR_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/antlr4_lib/antlr-4.9.3-complete.jar CACHE PATH "antlr4 generator JAR file") # add macros to generate ANTLR Cpp code from grammar find_package(ANTLR REQUIRED) @@ -80,13 +80,15 @@ antlr_target(FasmParser antlr/FasmParser.g4 PARSER VISITOR # line 1: Skip lines starting in #define # 2: Extract TAGS(...) from dependencies # 3: Convert from TAGS('c', long_name) -> long_name = b'c, write to file -add_custom_target(tags.py ALL +add_custom_command(OUTPUT tags.py COMMAND grep -ve ^\#define ${CMAKE_CURRENT_SOURCE_DIR}/ParseFasm.cpp | grep -hoe TAG\([^\)]*\) | - sed -e s/TAG\(\\\(.*\\\),\ \\\(.*\\\)\)/\\2\ =\ b\\1/ > tags.py + sed -e s/TAG\(\\\(.*\\\),\ \\\(.*\\\)\)/\\2\ =\ b\\1/ > ${CMAKE_CURRENT_BINARY_DIR}/tags.py DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ParseFasm.cpp VERBATIM ) +add_custom_target(tags_py ALL DEPENDS tags.py) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tags.py TYPE LIB) # Include generated files in project environment include_directories(${ANTLR_FasmLexer_OUTPUT_DIR}) @@ -97,6 +99,7 @@ add_library(parse_fasm SHARED ParseFasm.cpp ${ANTLR_FasmLexer_CXX_OUTPUTS} ${ANTLR_FasmParser_CXX_OUTPUTS}) target_link_libraries(parse_fasm ${ANTLR4_RUNTIME}) +install(TARGETS parse_fasm) #target_compile_options(parse_fasm PRIVATE -Wno-attributes) # Disable warning from antlr4-runtime add_executable(parse_fasm_tests @@ -105,6 +108,7 @@ add_executable(parse_fasm_tests ${ANTLR_FasmParser_CXX_OUTPUTS}) target_link_libraries(parse_fasm_tests ${ANTLR4_RUNTIME}) target_link_libraries(parse_fasm_tests gtest_main) +target_link_libraries(parse_fasm_tests gtest) #target_compile_options(parse_fasm_tests PRIVATE -Wno-attributes) # Disable warning from antlr4-runtime # Standalone executable @@ -122,5 +126,3 @@ include(CTest) add_test(NAME parse_fasm_tests COMMAND parse_fasm_tests) enable_testing() - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tags.py DESTINATION .)